LineIterator.h 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. #ifndef LLVM_SUPPORT_LINEITERATOR_H
  9. #define LLVM_SUPPORT_LINEITERATOR_H
  10. #include "llvm/ADT/Optional.h"
  11. #include "llvm/ADT/StringRef.h"
  12. #include "llvm/Support/DataTypes.h"
  13. #include "llvm/Support/MemoryBufferRef.h"
  14. #include <iterator>
  15. namespace llvm {
  16. class MemoryBuffer;
  17. /// A forward iterator which reads text lines from a buffer.
  18. ///
  19. /// This class provides a forward iterator interface for reading one line at
  20. /// a time from a buffer. When default constructed the iterator will be the
  21. /// "end" iterator.
  22. ///
  23. /// The iterator is aware of what line number it is currently processing. It
  24. /// strips blank lines by default, and comment lines given a comment-starting
  25. /// character.
  26. ///
  27. /// Note that this iterator requires the buffer to be nul terminated.
  28. class line_iterator {
  29. Optional<MemoryBufferRef> Buffer;
  30. char CommentMarker = '\0';
  31. bool SkipBlanks = true;
  32. unsigned LineNumber = 1;
  33. StringRef CurrentLine;
  34. public:
  35. using iterator_category = std::forward_iterator_tag;
  36. using value_type = StringRef;
  37. using difference_type = std::ptrdiff_t;
  38. using pointer = value_type *;
  39. using reference = value_type &;
  40. /// Default construct an "end" iterator.
  41. line_iterator() = default;
  42. /// Construct a new iterator around an unowned memory buffer.
  43. explicit line_iterator(const MemoryBufferRef &Buffer, bool SkipBlanks = true,
  44. char CommentMarker = '\0');
  45. /// Construct a new iterator around some memory buffer.
  46. explicit line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks = true,
  47. char CommentMarker = '\0');
  48. /// Return true if we've reached EOF or are an "end" iterator.
  49. bool is_at_eof() const { return !Buffer; }
  50. /// Return true if we're an "end" iterator or have reached EOF.
  51. bool is_at_end() const { return is_at_eof(); }
  52. /// Return the current line number. May return any number at EOF.
  53. int64_t line_number() const { return LineNumber; }
  54. /// Advance to the next (non-empty, non-comment) line.
  55. line_iterator &operator++() {
  56. advance();
  57. return *this;
  58. }
  59. line_iterator operator++(int) {
  60. line_iterator tmp(*this);
  61. advance();
  62. return tmp;
  63. }
  64. /// Get the current line as a \c StringRef.
  65. StringRef operator*() const { return CurrentLine; }
  66. const StringRef *operator->() const { return &CurrentLine; }
  67. friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) {
  68. return LHS.Buffer == RHS.Buffer &&
  69. LHS.CurrentLine.begin() == RHS.CurrentLine.begin();
  70. }
  71. friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) {
  72. return !(LHS == RHS);
  73. }
  74. private:
  75. /// Advance the iterator to the next line.
  76. void advance();
  77. };
  78. }
  79. #endif