[flang-commits] [flang] [flang][OpenMP] Add `is_range<R>` trait to detect classes with begin/end, NFC (PR #183615)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Thu Feb 26 12:47:52 PST 2026


https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/183615

None

>From afe985ca035f5a7a124dc04f51dda6f0c56cb732 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 26 Feb 2026 13:58:37 -0600
Subject: [PATCH] [flang][OpenMP] Add is_range<R> trait to detect classes with
 begin/end, NFC

---
 flang/include/flang/Parser/openmp-utils.h | 25 +++++++++++++++--------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index 65a9890d85293..6cfaf8bb21712 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -239,6 +239,19 @@ struct OmpAllocateInfo {
 
 OmpAllocateInfo SplitOmpAllocate(const OmpAllocateDirective &x);
 
+template <typename R, typename = void, typename = void> struct is_range {
+  static constexpr bool value{false};
+};
+
+template <typename R>
+struct is_range<R, //
+    std::void_t<decltype(std::declval<R>().begin())>,
+    std::void_t<decltype(std::declval<R>().end())>> {
+  static constexpr bool value{true};
+};
+
+template <typename R> constexpr bool is_range_v = is_range<R>::value;
+
 // Iterate over a range of parser::Block::const_iterator's. When the end
 // of the range is reached, the iterator becomes invalid.
 // Treat BLOCK constructs as if they were transparent, i.e. as if the
@@ -296,9 +309,7 @@ struct ExecutionPartIterator {
     stack_.emplace_back(b, e, c);
     adjust();
   }
-  template <typename R, //
-      typename = decltype(std::declval<R>().begin()),
-      typename = decltype(std::declval<R>().end())>
+  template <typename R, typename = std::enable_if_t<is_range_v<R>>>
   ExecutionPartIterator(const R &range, Step stepping = Step::Default,
       const ExecutionPartConstruct *construct = nullptr)
       : ExecutionPartIterator(range.begin(), range.end(), stepping, construct) {
@@ -368,9 +379,7 @@ template <typename Iterator = ExecutionPartIterator> struct ExecutionPartRange {
       Step stepping = Step::Default,
       const ExecutionPartConstruct *owner = nullptr)
       : begin_(begin, end, stepping, owner), end_() {}
-  template <typename R, //
-      typename = decltype(std::declval<R>().begin()),
-      typename = decltype(std::declval<R>().end())>
+  template <typename R, typename = std::enable_if_t<is_range_v<R>>>
   ExecutionPartRange(const R &range, Step stepping = Step::Default,
       const ExecutionPartConstruct *owner = nullptr)
       : ExecutionPartRange(range.begin(), range.end(), stepping, owner) {}
@@ -390,9 +399,7 @@ struct LoopNestIterator : public ExecutionPartIterator {
       : ExecutionPartIterator(b, e, s, c) {
     adjust();
   }
-  template <typename R, //
-      typename = decltype(std::declval<R>().begin()),
-      typename = decltype(std::declval<R>().end())>
+  template <typename R, typename = std::enable_if_t<is_range_v<R>>>
   LoopNestIterator(const R &range, Step stepping = Step::Default,
       const ExecutionPartConstruct *construct = nullptr)
       : LoopNestIterator(range.begin(), range.end(), stepping, construct) {}



More information about the flang-commits mailing list