1274955Ssvnmir//===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===//
2274955Ssvnmir//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6274955Ssvnmir//
7274955Ssvnmir//===----------------------------------------------------------------------===//
8274955Ssvnmir/// \file
9274955Ssvnmir/// This provides a very simple, boring adaptor for a begin and end iterator
10274955Ssvnmir/// into a range type. This should be used to build range views that work well
11274955Ssvnmir/// with range based for loops and range based constructors.
12274955Ssvnmir///
13274955Ssvnmir/// Note that code here follows more standards-based coding conventions as it
14274955Ssvnmir/// is mirroring proposed interfaces for standardization.
15274955Ssvnmir///
16274955Ssvnmir//===----------------------------------------------------------------------===//
17274955Ssvnmir
18274955Ssvnmir#ifndef LLVM_ADT_ITERATOR_RANGE_H
19274955Ssvnmir#define LLVM_ADT_ITERATOR_RANGE_H
20274955Ssvnmir
21321369Sdim#include <iterator>
22274955Ssvnmir#include <utility>
23274955Ssvnmir
24274955Ssvnmirnamespace llvm {
25274955Ssvnmir
26341825Sdim/// A range adaptor for a pair of iterators.
27274955Ssvnmir///
28274955Ssvnmir/// This just wraps two iterators into a range-compatible interface. Nothing
29274955Ssvnmir/// fancy at all.
30274955Ssvnmirtemplate <typename IteratorT>
31274955Ssvnmirclass iterator_range {
32274955Ssvnmir  IteratorT begin_iterator, end_iterator;
33274955Ssvnmir
34274955Ssvnmirpublic:
35296417Sdim  //TODO: Add SFINAE to test that the Container's iterators match the range's
36296417Sdim  //      iterators.
37296417Sdim  template <typename Container>
38296417Sdim  iterator_range(Container &&c)
39296417Sdim  //TODO: Consider ADL/non-member begin/end calls.
40296417Sdim      : begin_iterator(c.begin()), end_iterator(c.end()) {}
41274955Ssvnmir  iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
42274955Ssvnmir      : begin_iterator(std::move(begin_iterator)),
43274955Ssvnmir        end_iterator(std::move(end_iterator)) {}
44274955Ssvnmir
45274955Ssvnmir  IteratorT begin() const { return begin_iterator; }
46274955Ssvnmir  IteratorT end() const { return end_iterator; }
47360784Sdim  bool empty() const { return begin_iterator == end_iterator; }
48274955Ssvnmir};
49274955Ssvnmir
50341825Sdim/// Convenience function for iterating over sub-ranges.
51274955Ssvnmir///
52274955Ssvnmir/// This provides a bit of syntactic sugar to make using sub-ranges
53274955Ssvnmir/// in for loops a bit easier. Analogous to std::make_pair().
54274955Ssvnmirtemplate <class T> iterator_range<T> make_range(T x, T y) {
55274955Ssvnmir  return iterator_range<T>(std::move(x), std::move(y));
56274955Ssvnmir}
57280031Sdim
58280031Sdimtemplate <typename T> iterator_range<T> make_range(std::pair<T, T> p) {
59280031Sdim  return iterator_range<T>(std::move(p.first), std::move(p.second));
60274955Ssvnmir}
61296417Sdim
62280031Sdim}
63274955Ssvnmir
64274955Ssvnmir#endif
65