[PATCH] D45490: [ADT] - Add llvm::make_mapped_range

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 10 08:04:21 PDT 2018


grimar created this revision.
grimar added reviewers: espindola, dblaikie, chandlerc.
grimar added a dependent revision: D45166: [ELF] - Introduce helper for iterating over linker commands..

This adds a helper for convenience to create mapped iterator ranges.

For use in https://reviews.llvm.org/D45166.


https://reviews.llvm.org/D45490

Files:
  include/llvm/ADT/STLExtras.h
  unittests/ADT/MappedIteratorTest.cpp


Index: unittests/ADT/MappedIteratorTest.cpp
===================================================================
--- unittests/ADT/MappedIteratorTest.cpp
+++ unittests/ADT/MappedIteratorTest.cpp
@@ -48,4 +48,12 @@
   EXPECT_EQ(M[1], 42) << "assignment should have modified M";
 }
 
+TEST(MappedIteratorTest, MappedRange) {
+  std::vector<int> V({0, 1, 2});
+
+  size_t I = 1;
+  for (int Val : make_mapped_range(V, [](int X) { return X + 1; }))
+    EXPECT_EQ(Val, I++) << "should have applied function in dereference";
+}
+
 } // anonymous namespace
Index: include/llvm/ADT/STLExtras.h
===================================================================
--- include/llvm/ADT/STLExtras.h
+++ include/llvm/ADT/STLExtras.h
@@ -196,12 +196,16 @@
   mapped_iterator(ItTy U, FuncTy F)
     : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
 
+  // Constructor for the end iterator. Not dereferencable, hence no FuncTy.
+  mapped_iterator(ItTy U)
+      : mapped_iterator::iterator_adaptor_base(std::move(U)) {}
+
   ItTy getCurrent() { return this->I; }
 
-  FuncReturnTy operator*() { return F(*this->I); }
+  FuncReturnTy operator*() { return (*F)(*this->I); }
 
 private:
-  FuncTy F;
+  Optional<FuncTy> F;
 };
 
 // map_iterator - Provide a convenient way to create mapped_iterators, just like
@@ -211,6 +215,20 @@
   return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
 }
 
+template <typename ItT, typename PredicateT>
+using mapped_iterator_range = iterator_range<mapped_iterator<ItT, PredicateT>>;
+
+/// Convenience function that takes a range of elements and a predicate,
+/// and return a new mapped_iterator range.
+template <typename RangeT, typename PredicateT>
+mapped_iterator_range<detail::IterOfRange<RangeT>, PredicateT>
+make_mapped_range(RangeT &&Range, PredicateT Pred) {
+  using MappedItT = mapped_iterator<detail::IterOfRange<RangeT>, PredicateT>;
+  auto I = MappedItT(std::begin(std::forward<RangeT>(Range)), std::move(Pred));
+  auto E = MappedItT(std::end(std::forward<RangeT>(Range)));
+  return make_range(I, E);
+}
+
 /// Helper to determine if type T has a member called rbegin().
 template <typename Ty> class has_rbegin_impl {
   using yes = char[1];


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45490.141852.patch
Type: text/x-patch
Size: 2220 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180410/a90e3c08/attachment.bin>


More information about the llvm-commits mailing list