Add ityp::SpanFromUntyped

This helps create ityp::span from the Dawn C interface of pointer +
count.

Bug: dawn:2222
Change-Id: I78309871b689f6544746fb5f05ebd9a31cd92649
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162501
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/common/ityp_span.h b/src/dawn/common/ityp_span.h
index 0a299b3..e6b364f 100644
--- a/src/dawn/common/ityp_span.h
+++ b/src/dawn/common/ityp_span.h
@@ -95,6 +95,14 @@
     Index mSize;
 };
 
+// ityp::SpanFromUntyped<Index>(myValues, myValueCount) creates a span<Index, Value> from a C-style
+// span that's without a TypedInteger index. It is useful at the interface between code that doesn't
+// use ityp and code that does.
+template <typename Index, typename Value>
+span<Index, Value> SpanFromUntyped(Value* data, size_t size) {
+    return {data, Index{static_cast<UnderlyingType<Index>>(size)}};
+}
+
 }  // namespace dawn::ityp
 
 #endif  // SRC_DAWN_COMMON_ITYP_SPAN_H_
diff --git a/src/dawn/tests/unittests/ITypSpanTests.cpp b/src/dawn/tests/unittests/ITypSpanTests.cpp
index 36ca508..9de555d 100644
--- a/src/dawn/tests/unittests/ITypSpanTests.cpp
+++ b/src/dawn/tests/unittests/ITypSpanTests.cpp
@@ -96,5 +96,31 @@
     ASSERT_EQ(constSpan.data(), &constSpan[Key(0)]);
 }
 
+// Test the utility SpanFromUntyped
+TEST_F(ITypSpanTest, SpanFromUntyped) {
+    // Test creating an empty span.
+    {
+        Val* values = nullptr;
+        Span span = ityp::SpanFromUntyped<Key>(values, 0);
+        ASSERT_EQ(nullptr, span.data());
+        ASSERT_EQ(Key(0), span.size());
+    }
+    // Test creating a one element span.
+    {
+        Val value = Val(25);
+        Span span = ityp::SpanFromUntyped<Key>(&value, 1);
+        ASSERT_EQ(&value, span.data());
+        ASSERT_EQ(Key(1), span.size());
+        ASSERT_EQ(value, span[Key(0)]);
+    }
+    // Test creating a multi-element span.
+    {
+        std::array<Val, 10> arr = {};
+        Span span = ityp::SpanFromUntyped<Key>(arr.data(), arr.size());
+        ASSERT_EQ(arr.data(), span.data());
+        ASSERT_EQ(arr.size(), static_cast<size_t>(span.size()));
+    }
+}
+
 }  // anonymous namespace
 }  // namespace dawn