136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===- LineIterator.h - Iterator to read a text buffer's lines --*- C++ -*-===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef LLVM_SUPPORT_LINEITERATOR_H__
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define LLVM_SUPPORT_LINEITERATOR_H__
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringRef.h"
14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/DataTypes.h"
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <iterator>
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm {
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass MemoryBuffer;
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief A forward iterator which reads non-blank text lines from a buffer.
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// This class provides a forward iterator interface for reading one line at
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// a time from a buffer. When default constructed the iterator will be the
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// "end" iterator.
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// The iterator also is aware of what line number it is currently processing
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// and can strip comment lines given the comment-starting character.
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Note that this iterator requires the buffer to be nul terminated.
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass line_iterator
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : public std::iterator<std::forward_iterator_tag, StringRef> {
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MemoryBuffer *Buffer;
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  char CommentMarker;
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned LineNumber;
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef CurrentLine;
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Default construct an "end" iterator.
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  line_iterator() : Buffer(nullptr) {}
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Construct a new iterator around some memory buffer.
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0');
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Return true if we've reached EOF or are an "end" iterator.
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool is_at_eof() const { return !Buffer; }
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Return true if we're an "end" iterator or have reached EOF.
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool is_at_end() const { return is_at_eof(); }
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Return the current line number. May return any number at EOF.
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t line_number() const { return LineNumber; }
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Advance to the next (non-empty, non-comment) line.
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  line_iterator &operator++() {
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    advance();
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return *this;
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  line_iterator operator++(int) {
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    line_iterator tmp(*this);
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    advance();
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return tmp;
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Get the current line as a \c StringRef.
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef operator*() const { return CurrentLine; }
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const StringRef *operator->() const { return &CurrentLine; }
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) {
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return LHS.Buffer == RHS.Buffer &&
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           LHS.CurrentLine.begin() == RHS.CurrentLine.begin();
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) {
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return !(LHS == RHS);
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate:
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Advance the iterator to the next line.
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void advance();
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif // LLVM_SUPPORT_LINEITERATOR_H__
86