[Consumed][NFC] Refactor handleCall to take function argument list.
authorNicholas Allegra <comexk@gmail.com>
Thu, 26 Sep 2019 23:47:18 +0000 (23:47 +0000)
committerNicholas Allegra <comexk@gmail.com>
Thu, 26 Sep 2019 23:47:18 +0000 (23:47 +0000)
Differential Revision: https://reviews.llvm.org/D67569

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373034 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/STLExtras.h
include/llvm/ADT/iterator_range.h

index 274933bc5204b07ebf086c9488f41a792a466a13..430707cbd79d33cade5cd1d0270ca58708cc4156 100644 (file)
@@ -1573,6 +1573,14 @@ template <class Ptr> auto to_address(const Ptr &P) -> decltype(P.operator->()) {
 }
 template <class T> constexpr T *to_address(T *P) { return P; }
 
+template <typename R>
+auto index(R &&TheRange,
+  typename std::iterator_traits<detail::IterOfRange<R>>::difference_type N)
+  -> decltype(TheRange.begin()[N]) {
+  assert(N < TheRange.end() - TheRange.begin() && "Index out of range!");
+  return TheRange.begin()[N];
+}
+
 } // end namespace llvm
 
 #endif // LLVM_ADT_STLEXTRAS_H
index 774c7c4e3366e503ebd9972a84053ddf6ff4e8ec..3bb9231441c998e23fde7d765159b0e52e48c1fc 100644 (file)
 
 #include <iterator>
 #include <utility>
+#include <cassert>
 
 namespace llvm {
 
+template <typename T>
+constexpr bool is_random_iterator() {
+  return std::is_same<
+    typename std::iterator_traits<T>::iterator_category,
+    std::random_access_iterator_tag>::value;
+}
+
 /// A range adaptor for a pair of iterators.
 ///
 /// This just wraps two iterators into a range-compatible interface. Nothing
@@ -58,11 +66,31 @@ template <typename T> iterator_range<T> make_range(std::pair<T, T> p) {
   return iterator_range<T>(std::move(p.first), std::move(p.second));
 }
 
+/// Non-random-iterator version
 template <typename T>
-iterator_range<decltype(adl_begin(std::declval<T>()))> drop_begin(T &&t,
-                                                                  int n) {
-  return make_range(std::next(adl_begin(t), n), adl_end(t));
+auto drop_begin(T &&t, int n) ->
+  typename std::enable_if<!is_random_iterator<decltype(adl_begin(t))>(),
+  iterator_range<decltype(adl_begin(t))>>::type {
+  auto begin = adl_begin(t);
+  auto end = adl_end(t);
+  for (int i = 0; i < n; i++) {
+    assert(begin != end);
+    ++begin;
+  }
+  return make_range(begin, end);
 }
+
+/// Optimized version for random iterators
+template <typename T>
+auto drop_begin(T &&t, int n) ->
+  typename std::enable_if<is_random_iterator<decltype(adl_begin(t))>(),
+  iterator_range<decltype(adl_begin(t))>>::type {
+  auto begin = adl_begin(t);
+  auto end = adl_end(t);
+  assert(end - begin >= n && "Dropping more elements than exist!");
+  return make_range(std::next(begin, n), end);
+}
+
 }
 
 #endif