[cfe-commits] r43901 - /cfe/trunk/include/clang/Rewrite/RewriteRope.h
Chris Lattner
sabre at nondot.org
Thu Nov 8 11:39:57 PST 2007
Author: lattner
Date: Thu Nov 8 13:39:57 2007
New Revision: 43901
URL: http://llvm.org/viewvc/llvm-project?rev=43901&view=rev
Log:
significantly simplify the implementation of RewriteRope by changing the
implementation to be list<RopePiece> instead of vector<RopePiece*>.
Modified:
cfe/trunk/include/clang/Rewrite/RewriteRope.h
Modified: cfe/trunk/include/clang/Rewrite/RewriteRope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/RewriteRope.h?rev=43901&r1=43900&r2=43901&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/RewriteRope.h (original)
+++ cfe/trunk/include/clang/Rewrite/RewriteRope.h Thu Nov 8 13:39:57 2007
@@ -15,7 +15,7 @@
#define LLVM_CLANG_REWRITEROPE_H
#include "llvm/ADT/iterator"
-#include <vector>
+#include <list>
namespace clang {
@@ -56,18 +56,18 @@
class RewriteRope;
-template <typename CharType, typename PieceType>
+template <typename CharType, typename PieceIterType>
class RewriteRopeIterator :
- public std::iterator<std::random_access_iterator_tag, CharType, ptrdiff_t> {
- PieceType *CurPiece;
+ public bidirectional_iterator<CharType, ptrdiff_t> {
+ PieceIterType CurPiece;
unsigned CurChar;
friend class RewriteRope;
public:
- RewriteRopeIterator(PieceType *curPiece, unsigned curChar)
+ RewriteRopeIterator(const PieceIterType &curPiece, unsigned curChar)
: CurPiece(curPiece), CurChar(curChar) {}
CharType &operator*() const {
- return (**CurPiece)[CurChar];
+ return (*CurPiece)[CurChar];
}
bool operator==(const RewriteRopeIterator &RHS) const {
@@ -78,7 +78,7 @@
}
inline RewriteRopeIterator& operator++() { // Preincrement
- if (CurChar+1 < (*CurPiece)->size())
+ if (CurChar+1 < CurPiece->size())
++CurChar;
else {
CurChar = 0;
@@ -94,41 +94,23 @@
RewriteRopeIterator operator+(int Offset) const {
assert(Offset >= 0 && "FIXME: Only handle forward case so far!");
- PieceType *Piece = CurPiece;
+ PieceIterType Piece = CurPiece;
unsigned Char = CurChar;
- while (Char+Offset >= (*Piece)->size()) {
- Offset -= (*Piece)->size()-Char;
+ while (Char+Offset >= Piece->size()) {
+ Offset -= Piece->size()-Char;
++Piece;
Char = 0;
}
Char += Offset;
return RewriteRopeIterator(Piece, Char);
}
-
- ptrdiff_t operator-(const RewriteRopeIterator &RHS) const {
- if (CurPiece < RHS.CurPiece ||
- (CurPiece == RHS.CurPiece && CurChar < RHS.CurChar))
- return -RHS.operator-(*this);
-
- PieceType *Piece = RHS.CurPiece;
- unsigned Char = RHS.CurChar;
-
- unsigned Offset = 0;
- while (Piece != CurPiece) {
- Offset += (*Piece)->size()-Char;
- Char = 0;
- ++Piece;
- }
-
- return Offset + CurChar-Char;
- }
};
/// RewriteRope - A powerful string class, todo generalize this.
class RewriteRope {
- std::vector<RopePiece*> Chunks;
+ std::list<RopePiece> Chunks;
unsigned CurSize;
/// We allocate space for string data out of a buffer of size AllocChunkSize.
@@ -140,123 +122,94 @@
RewriteRope() : CurSize(0), AllocBuffer(0), AllocOffs(AllocChunkSize) {}
~RewriteRope() { clear(); }
- typedef RewriteRopeIterator<char, RopePiece*> iterator;
- typedef RewriteRopeIterator<const char, RopePiece* const> const_iterator;
- iterator begin() {
- if (Chunks.empty()) return iterator(0,0);
- return iterator(&Chunks[0], 0);
- }
- iterator end() {
- if (Chunks.empty()) return iterator(0,0);
- return iterator(&Chunks[0]+Chunks.size(), 0);
- }
-
- const_iterator begin() const {
- if (Chunks.empty()) return const_iterator(0,0);
- return const_iterator(&Chunks[0], 0);
- }
- const_iterator end() const {
- if (Chunks.empty()) return const_iterator(0,0);
- return const_iterator(&Chunks[0]+Chunks.size(), 0);
- }
-
+ typedef RewriteRopeIterator<char, std::list<RopePiece>::iterator> iterator;
+ typedef RewriteRopeIterator<const char,
+ std::list<RopePiece>::const_iterator> const_iterator;
+
+ iterator begin() { return iterator(Chunks.begin(), 0); }
+ iterator end() { return iterator(Chunks.end(), 0); }
+ const_iterator begin() const { return const_iterator(Chunks.begin(), 0); }
+ const_iterator end() const { return const_iterator(Chunks.end(), 0); }
unsigned size() const { return CurSize; }
void clear() {
- for (unsigned i = 0, e = Chunks.size(); i != e; ++i)
- delete Chunks[i];
Chunks.clear();
CurSize = 0;
}
void assign(const char *Start, const char *End) {
clear();
- Chunks.push_back(new RopePiece(MakeRopeString(Start, End)));
+ Chunks.push_back(MakeRopeString(Start, End));
CurSize = End-Start;
}
void insert(iterator Loc, const char *Start, const char *End) {
if (Start == End) return;
-
- unsigned ChunkNo = SplitAt(Loc);
-
- Chunks.insert(Chunks.begin()+ChunkNo,
- new RopePiece(MakeRopeString(Start, End)));
+ Chunks.insert(SplitAt(Loc), MakeRopeString(Start, End));
CurSize += End-Start;
}
void erase(iterator Start, iterator End) {
if (Start == End) return;
- unsigned StartChunkIdx = getChunkIdx(Start);
- unsigned EndChunkIdx = getChunkIdx(End);
+ //unsigned StartChunkIdx = getChunkIdx(Start);
+ //unsigned EndChunkIdx = getChunkIdx(End);
// If erase is localized within the same chunk, this is a degenerate case.
- if (StartChunkIdx == EndChunkIdx) {
- RopePiece *Chunk = Chunks[StartChunkIdx];
+ if (Start.CurPiece == End.CurPiece) {
+ RopePiece &Chunk = *Start.CurPiece;
unsigned NumDel = End.CurChar-Start.CurChar;
CurSize -= NumDel;
// If deleting from start of chunk, just adjust range.
if (Start.CurChar == 0) {
- if (Chunk->EndOffs != End.CurChar) {
- Chunk->StartOffs += NumDel;
- } else {
- // Deleting entire chunk, remove it.
- delete Chunk;
- Chunks.erase(Chunks.begin()+StartChunkIdx);
- }
+ if (Chunk.EndOffs != End.CurChar)
+ Chunk.StartOffs += NumDel;
+ else // Deleting entire chunk.
+ Chunks.erase(End.CurPiece);
return;
}
// If deleting to the end of chunk, just adjust range.
- if (End.CurChar == Chunk->size()) {
- Chunk->EndOffs -= NumDel;
+ if (End.CurChar == Chunk.size()) {
+ Chunk.EndOffs -= NumDel;
return;
}
// If deleting the middle of a chunk, split this chunk and adjust the end
// piece.
- unsigned NewIdx = SplitAt(Start);
- Chunk = Chunks[NewIdx];
- Chunk->StartOffs += End.CurChar-Start.CurChar;
-
+ SplitAt(Start)->StartOffs += NumDel;
return;
}
-
// Otherwise, the start chunk and the end chunk are different.
-
+ std::list<RopePiece>::iterator CurPiece = Start.CurPiece;
+
// Delete the end of the start chunk. If it is the whole thing, remove it.
{
- RopePiece *StartChunk = Chunks[StartChunkIdx];
- unsigned NumDel = StartChunk->size()-Start.CurChar;
+ RopePiece &StartChunk = *CurPiece;
+ unsigned NumDel = StartChunk.size()-Start.CurChar;
CurSize -= NumDel;
if (Start.CurChar == 0) {
// Delete the whole chunk.
- delete StartChunk;
- Chunks.erase(Chunks.begin()+StartChunkIdx);
- --EndChunkIdx;
+ Chunks.erase(CurPiece++);
} else {
// Otherwise, just move the end of chunk marker up.
- StartChunk->EndOffs -= NumDel;
- ++StartChunkIdx;
+ StartChunk.EndOffs -= NumDel;
+ ++CurPiece;
}
}
// If deleting a span of chunks, nuke them all now.
- while (StartChunkIdx != EndChunkIdx) {
- CurSize -= Chunks[StartChunkIdx]->size();
- delete Chunks[StartChunkIdx];
- Chunks.erase(Chunks.begin()+StartChunkIdx);
- --EndChunkIdx;
+ while (CurPiece != End.CurPiece) {
+ CurSize -= CurPiece->size();
+ Chunks.erase(CurPiece++);
}
// Finally, erase the start of the end chunk if appropriate.
if (End.CurChar != 0) {
- RopePiece *EndChunk = Chunks[EndChunkIdx];
- EndChunk->StartOffs += End.CurChar;
+ End.CurPiece->StartOffs += End.CurChar;
CurSize -= End.CurChar;
}
}
@@ -293,38 +246,29 @@
return RopePiece(AllocBuffer, 0, Len);
}
- unsigned getChunkIdx(iterator Loc) const {
- // Return the loc idx of the specified chunk, handling empty ropes.
- return Loc.CurPiece == 0 ? 0 : Loc.CurPiece - &Chunks[0];
- }
-
/// SplitAt - If the specified iterator position has a non-zero character
/// number, split the specified buffer up. This guarantees that the specified
/// iterator is at the start of a chunk. Return the chunk it is at the start
/// of.
- unsigned SplitAt(iterator Loc) {
- unsigned ChunkIdx = getChunkIdx(Loc);
+ std::list<RopePiece>::iterator SplitAt(iterator Loc) {
+ std::list<RopePiece>::iterator Chunk = Loc.CurPiece;
// If the specified position is at the start of a piece, return it.
if (Loc.CurChar == 0)
- return ChunkIdx;
+ return Chunk;
// Otherwise, we have to split the specified piece in half, inserting the
- // new piece into the vector of pieces.
- RopePiece *CurPiece = *Loc.CurPiece;
+ // new piece into the list of pieces.
// Make a new piece for the prefix part.
- RopePiece *NewPiece = new RopePiece(CurPiece->StrData, CurPiece->StartOffs,
- CurPiece->StartOffs+Loc.CurChar);
+ Chunks.insert(Chunk, RopePiece(Chunk->StrData, Chunk->StartOffs,
+ Chunk->StartOffs+Loc.CurChar));
// Make the current piece refer the suffix part.
- CurPiece->StartOffs += Loc.CurChar;
-
- // Insert the new piece.
- Chunks.insert(Chunks.begin()+ChunkIdx, NewPiece);
+ Chunk->StartOffs += Loc.CurChar;
// Return the old chunk, which is the suffix.
- return ChunkIdx+1;
+ return Chunk;
}
};
More information about the cfe-commits
mailing list