Skip to content

Conversation

@mtrofin
Copy link
Member

@mtrofin mtrofin commented Oct 30, 2025

Adding a static_cast_to​ over a range as a convenience.

Copy link
Member Author

mtrofin commented Oct 30, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@llvmbot
Copy link
Member

llvmbot commented Oct 30, 2025

@llvm/pr-subscribers-llvm-adt

Author: Mircea Trofin (mtrofin)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/165803.diff

2 Files Affected:

  • (modified) llvm/include/llvm/ADT/STLExtras.h (+6)
  • (modified) llvm/unittests/ADT/STLExtrasTest.cpp (+7)
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index a9841c6651b72..f65d08cafbdc6 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -1704,6 +1704,12 @@ auto sum_of(R &&Range, E Init = E{0}) {
   return accumulate(std::forward<R>(Range), std::move(Init));
 }
 
+/// Return a range where each value of `R` is static_cast to `T`
+template <typename T, typename R>
+auto static_cast_to(R &&Range) {
+  return map_range(Range, [](const auto &V) { return static_cast<T>(V); });
+}
+
 /// Returns the product of all values in `Range` with `Init` initial value.
 /// The default initial value is 1.
 template <typename R, typename E = detail::ValueOfRange<R>>
diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index 966b1f01e8a31..f9341dd64c999 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1669,6 +1669,13 @@ TEST(STLExtrasTest, SumOf) {
   EXPECT_EQ(sum_of(V3), 3.0f);
 }
 
+TEST(STLExtrasTest, StaticCastTo) { 
+  std::vector<int32_t> R{1, 2, 3};
+  EXPECT_TRUE(all_of(R, [](auto V) { return sizeof(V) == sizeof(int32_t); }));
+  EXPECT_TRUE(all_of(static_cast_to<int64_t>(R),
+                     [](auto V) { return sizeof(V) == sizeof(int64_t); }));
+}
+
 TEST(STLExtrasTest, ProductOf) {
   EXPECT_EQ(product_of(std::vector<int>()), 1);
   EXPECT_EQ(product_of(std::vector<int>(), 0), 0);

@github-actions
Copy link

github-actions bot commented Oct 30, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@mtrofin mtrofin force-pushed the users/mtrofin/10-30-_adt_introduce_a_static_cast_to_ branch from d07d953 to d4dd4af Compare October 30, 2025 23:48

/// Return a range where each value of `R` is static_cast to `T`
template <typename T, typename R> auto static_cast_to(R &&Range) {
return map_range(Range, [](const auto &V) { return static_cast<T>(V); });
Copy link
Contributor

@zwuis zwuis Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](auto &V) -> decltype(auto) { return static_cast<T>(V); }

Perhaps -> decltype(auto) is needed to allow returning reference.

}

/// Return a range where each value of `R` is static_cast to `T`
template <typename T, typename R> auto static_cast_to(R &&Range) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea makes sense but I wonder if we could pick a more descriptive function name, similar to other range functions

Copy link
Member

@kuhar kuhar Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One alternative would be not to add a range function and instead lift static cast to a function object like we did for llvm::IsaPred<T>. This way we can support variants based on dyn_cast/dyn_cast_if_present/cast.

I think that's a more general solution that composes with other functions like map_to_vector

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would the usage look like?

Copy link
Member

@kuhar kuhar Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map_range(Foo, StaticCastTo<unsigned>)
map_range(Bar, DynCastTo<IntegerAttr>)
map_to_vector(Baz, CastTo<FloatType>)

Copy link
Member

@kuhar kuhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cast function objects similar to IsaPred seem like a more general direction

@mtrofin mtrofin force-pushed the users/mtrofin/10-30-_adt_introduce_a_static_cast_to_ branch from d4dd4af to 40b6404 Compare October 31, 2025 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants