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];
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