[tint][utils] Add Offset and Truncate to Slice
Use them to simplify some IR code.
Change-Id: I43a23484b32003c1c759baf2f0ed33a03c474839
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/136461
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/ir/access.h b/src/tint/ir/access.h
index a2bd7eb..c798b13 100644
--- a/src/tint/ir/access.h
+++ b/src/tint/ir/access.h
@@ -38,8 +38,7 @@
/// @returns the accessor indices
utils::Slice<Value const* const> Indices() const {
- const auto& slice = operands_.Slice();
- return utils::Slice<Value const* const>(slice.data + 1, slice.len - 1, slice.cap - 1);
+ return operands_.Slice().Offset(1).Reinterpret<Value const* const>();
}
private:
diff --git a/src/tint/ir/break_if.h b/src/tint/ir/break_if.h
index 9fba486..b673cd8 100644
--- a/src/tint/ir/break_if.h
+++ b/src/tint/ir/break_if.h
@@ -38,8 +38,7 @@
/// @returns the branch arguments
utils::Slice<Value const* const> Args() const override {
- const auto& slice = operands_.Slice();
- return utils::Slice<Value const* const>(slice.data + 1, slice.len - 1, slice.cap - 1);
+ return operands_.Slice().Offset(1).Reinterpret<Value const* const>();
}
/// @returns the break condition
diff --git a/src/tint/ir/user_call.h b/src/tint/ir/user_call.h
index 0f9b5ea..d165715 100644
--- a/src/tint/ir/user_call.h
+++ b/src/tint/ir/user_call.h
@@ -33,8 +33,7 @@
/// @returns the call arguments
utils::Slice<Value const* const> Args() const override {
- const auto& slice = operands_.Slice();
- return utils::Slice<Value const* const>(slice.data + 1, slice.len - 1, slice.cap - 1);
+ return operands_.Slice().Offset(1).Reinterpret<Value const* const>();
}
/// @returns the called function name
diff --git a/src/tint/utils/slice.h b/src/tint/utils/slice.h
index 3380d23..ca25949 100644
--- a/src/tint/utils/slice.h
+++ b/src/tint/utils/slice.h
@@ -162,6 +162,26 @@
/// @return the length of the slice
size_t Length() const { return len; }
+ /// Create a new slice that represents an offset into this slice
+ /// @param offset the number of elements to offset
+ /// @return the new slice
+ Slice<T> Offset(size_t offset) const {
+ if (offset > len) {
+ offset = len;
+ }
+ return Slice(data + offset, len - offset, cap - offset);
+ }
+
+ /// Create a new slice that represents a truncated version of this slice
+ /// @param length the new length
+ /// @return a new slice that is truncated to `length` elements
+ Slice<T> Truncate(size_t length) const {
+ if (length > len) {
+ length = len;
+ }
+ return Slice(data, length, length);
+ }
+
/// Index operator
/// @param i the element index. Must be less than `len`.
/// @returns a reference to the i'th element.
diff --git a/src/tint/utils/slice_test.cc b/src/tint/utils/slice_test.cc
index 319b678..5725870 100644
--- a/src/tint/utils/slice_test.cc
+++ b/src/tint/utils/slice_test.cc
@@ -142,5 +142,44 @@
}
}
+TEST(TintSliceTest, Offset) {
+ int elements[] = {1, 2, 3};
+
+ auto slice = Slice{elements};
+ auto offset = slice.Offset(1);
+ EXPECT_EQ(offset.Length(), 2u);
+ EXPECT_EQ(offset[0], 2);
+ EXPECT_EQ(offset[1], 3);
+}
+
+TEST(TintSliceTest, Offset_PastEnd) {
+ int elements[] = {1, 2, 3};
+
+ auto slice = Slice{elements};
+ auto offset = slice.Offset(4);
+ EXPECT_EQ(offset.Length(), 0u);
+}
+
+TEST(TintSliceTest, Truncate) {
+ int elements[] = {1, 2, 3};
+
+ auto slice = Slice{elements};
+ auto truncated = slice.Truncate(2);
+ EXPECT_EQ(truncated.Length(), 2u);
+ EXPECT_EQ(truncated[0], 1);
+ EXPECT_EQ(truncated[1], 2);
+}
+
+TEST(TintSliceTest, Truncate_PastEnd) {
+ int elements[] = {1, 2, 3};
+
+ auto slice = Slice{elements};
+ auto truncated = slice.Truncate(4);
+ EXPECT_EQ(truncated.Length(), 3u);
+ EXPECT_EQ(truncated[0], 1);
+ EXPECT_EQ(truncated[1], 2);
+ EXPECT_EQ(truncated[2], 3);
+}
+
} // namespace
} // namespace tint::utils