}
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
#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
return iterator_range<T>(std::move(p.first), std::move(p.second));
}
-/// Non-random-iterator version
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);
- for (int i = 0; i < n; i++) {
- assert(begin != end);
- ++begin;
- }
- return make_range(begin, end);
+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));
}
-
-/// 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