LineIterator.h revision 360784
1//===- LineIterator.h - Iterator to read a text buffer's lines --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_SUPPORT_LINEITERATOR_H
10#define LLVM_SUPPORT_LINEITERATOR_H
11
12#include "llvm/ADT/StringRef.h"
13#include "llvm/Support/DataTypes.h"
14#include <iterator>
15
16namespace llvm {
17
18class MemoryBuffer;
19
20/// A forward iterator which reads text lines from a buffer.
21///
22/// This class provides a forward iterator interface for reading one line at
23/// a time from a buffer. When default constructed the iterator will be the
24/// "end" iterator.
25///
26/// The iterator is aware of what line number it is currently processing. It
27/// strips blank lines by default, and comment lines given a comment-starting
28/// character.
29///
30/// Note that this iterator requires the buffer to be nul terminated.
31class line_iterator
32    : public std::iterator<std::forward_iterator_tag, StringRef> {
33  const MemoryBuffer *Buffer = nullptr;
34  char CommentMarker = '\0';
35  bool SkipBlanks = true;
36
37  unsigned LineNumber = 1;
38  StringRef CurrentLine;
39
40public:
41  /// Default construct an "end" iterator.
42  line_iterator() = default;
43
44  /// Construct a new iterator around some memory buffer.
45  explicit line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks = true,
46                         char CommentMarker = '\0');
47
48  /// Return true if we've reached EOF or are an "end" iterator.
49  bool is_at_eof() const { return !Buffer; }
50
51  /// Return true if we're an "end" iterator or have reached EOF.
52  bool is_at_end() const { return is_at_eof(); }
53
54  /// Return the current line number. May return any number at EOF.
55  int64_t line_number() const { return LineNumber; }
56
57  /// Advance to the next (non-empty, non-comment) line.
58  line_iterator &operator++() {
59    advance();
60    return *this;
61  }
62  line_iterator operator++(int) {
63    line_iterator tmp(*this);
64    advance();
65    return tmp;
66  }
67
68  /// Get the current line as a \c StringRef.
69  StringRef operator*() const { return CurrentLine; }
70  const StringRef *operator->() const { return &CurrentLine; }
71
72  friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) {
73    return LHS.Buffer == RHS.Buffer &&
74           LHS.CurrentLine.begin() == RHS.CurrentLine.begin();
75  }
76
77  friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) {
78    return !(LHS == RHS);
79  }
80
81private:
82  /// Advance the iterator to the next line.
83  void advance();
84};
85}
86
87#endif
88