git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49651 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-04-14 17:12:49 +00:00
Родитель 49a2fd2758
Коммит e5cd857f7e
2 изменённых файлов: 3 добавлений и 256 удалений

Просмотреть файл

@ -20,8 +20,6 @@
#include "llvm/Support/Casting.h"
//#define USE_ROPE_VECTOR
namespace clang {
struct RopeRefCountString {
@ -80,7 +78,6 @@ struct RopePiece {
#ifndef USE_ROPE_VECTOR
using llvm::dyn_cast;
using llvm::cast;
@ -735,73 +732,9 @@ public:
};
#endif // ifndef USE_ROPE_VECTOR
#ifdef USE_ROPE_VECTOR
class RewriteRope;
template <typename CharType, typename PieceIterType>
class RewriteRopeIterator :
public bidirectional_iterator<CharType, ptrdiff_t> {
PieceIterType CurPiece;
unsigned CurChar;
friend class RewriteRope;
public:
RewriteRopeIterator(const PieceIterType &curPiece, unsigned curChar)
: CurPiece(curPiece), CurChar(curChar) {}
CharType &operator*() const {
return (*CurPiece)[CurChar];
}
bool operator==(const RewriteRopeIterator &RHS) const {
return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
}
bool operator!=(const RewriteRopeIterator &RHS) const {
return !operator==(RHS);
}
inline RewriteRopeIterator& operator++() { // Preincrement
if (CurChar+1 < CurPiece->size())
++CurChar;
else {
CurChar = 0;
++CurPiece;
}
return *this;
}
RewriteRopeIterator operator+(int Offset) const {
assert(Offset >= 0 && "FIXME: Only handle forward case so far!");
PieceIterType Piece = CurPiece;
unsigned Char = CurChar;
while (Char+Offset >= Piece->size()) {
Offset -= Piece->size()-Char;
++Piece;
Char = 0;
}
Char += Offset;
return RewriteRopeIterator(Piece, Char);
}
inline RewriteRopeIterator operator++(int) { // Postincrement
RewriteRopeIterator tmp = *this; ++*this; return tmp;
}
};
#endif
/// RewriteRope - A powerful string class, todo generalize this.
class RewriteRope {
#ifdef USE_ROPE_VECTOR
// FIXME: This could be significantly faster by using a balanced binary tree
// instead of a list.
std::list<RopePiece> Chunks;
unsigned CurSize;
#else
RopePieceBTree Chunks;
#endif
/// We allocate space for string data out of a buffer of size AllocChunkSize.
/// This keeps track of how much space is left.
@ -810,16 +743,9 @@ class RewriteRope {
enum { AllocChunkSize = 4080 };
public:
RewriteRope() :
#ifdef USE_ROPE_VECTOR
CurSize(0),
#endif
AllocBuffer(0), AllocOffs(AllocChunkSize) {}
RewriteRope(const RewriteRope &RHS) : Chunks(RHS.Chunks),
#ifdef USE_ROPE_VECTOR
CurSize(RHS.CurSize),
#endif
AllocBuffer(0), AllocOffs(AllocChunkSize) {
RewriteRope() : AllocBuffer(0), AllocOffs(AllocChunkSize) {}
RewriteRope(const RewriteRope &RHS)
: Chunks(RHS.Chunks), AllocBuffer(0), AllocOffs(AllocChunkSize) {
}
~RewriteRope() {
@ -827,33 +753,16 @@ public:
AllocBuffer->dropRef();
}
#ifdef USE_ROPE_VECTOR
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; }
#else
typedef RopePieceBTree::iterator iterator;
typedef RopePieceBTree::iterator const_iterator;
iterator begin() const { return Chunks.begin(); }
iterator end() const { return Chunks.end(); }
unsigned size() const { return Chunks.size(); }
#endif
void clear() {
Chunks.clear();
#ifdef USE_ROPE_VECTOR
CurSize = 0;
#endif
}
#ifndef USE_ROPE_VECTOR
void assign(const char *Start, const char *End) {
clear();
Chunks.insert(0, MakeRopeString(Start, End));
@ -868,105 +777,6 @@ public:
if (NumBytes == 0) return;
Chunks.erase(Offset, NumBytes);
}
#endif
#ifdef USE_ROPE_VECTOR
void assign(const char *Start, const char *End) {
clear();
Chunks.push_back(MakeRopeString(Start, End));
CurSize = End-Start;
}
iterator getAtOffset(unsigned Offset) {
assert(Offset <= CurSize && "Offset out of range!");
if (Offset == CurSize) return iterator(Chunks.end(), 0);
std::list<RopePiece>::iterator Piece = Chunks.begin();
while (Offset >= Piece->size()) {
Offset -= Piece->size();
++Piece;
}
return iterator(Piece, Offset);
}
const_iterator getAtOffset(unsigned Offset) const {
assert(Offset <= CurSize && "Offset out of range!");
if (Offset == CurSize) return const_iterator(Chunks.end(), 0);
std::list<RopePiece>::const_iterator Piece = Chunks.begin();
while (Offset >= Piece->size()) {
Offset -= Piece->size();
++Piece;
}
return const_iterator(Piece, Offset);
}
void insert(iterator Loc, const char *Start, const char *End) {
if (Start == End) return;
Chunks.insert(SplitAt(Loc), MakeRopeString(Start, End));
CurSize += End-Start;
}
void erase(iterator Start, iterator End) {
if (Start == End) return;
// If erase is localized within the same chunk, this is a degenerate case.
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.
Chunks.erase(End.CurPiece);
return;
}
// If deleting to the end of chunk, just adjust range.
if (End.CurChar == Chunk.size()) {
Chunk.EndOffs -= NumDel;
return;
}
// If deleting the middle of a chunk, split this chunk and adjust the end
// piece.
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 = *CurPiece;
unsigned NumDel = StartChunk.size()-Start.CurChar;
CurSize -= NumDel;
if (Start.CurChar == 0) {
// Delete the whole chunk.
Chunks.erase(CurPiece++);
} else {
// Otherwise, just move the end of chunk marker up.
StartChunk.EndOffs -= NumDel;
++CurPiece;
}
}
// If deleting a span of chunks, nuke them all now.
while (CurPiece != End.CurPiece) {
CurSize -= CurPiece->size();
Chunks.erase(CurPiece++);
}
// Finally, erase the start of the end chunk if appropriate.
if (End.CurChar != 0) {
End.CurPiece->StartOffs += End.CurChar;
CurSize -= End.CurChar;
}
}
#endif
private:
RopePiece MakeRopeString(const char *Start, const char *End) {
@ -1008,34 +818,6 @@ private:
AllocBuffer->addRef();
return RopePiece(AllocBuffer, 0, Len);
}
#ifdef USE_ROPE_VECTOR
/// 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.
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 Chunk;
// Otherwise, we have to split the specified piece in half, inserting the
// new piece into the list of pieces.
// Make a new piece for the prefix part.
Chunks.insert(Chunk, RopePiece(Chunk->StrData, Chunk->StartOffs,
Chunk->StartOffs+Loc.CurChar));
// Make the current piece refer the suffix part.
Chunk->StartOffs += Loc.CurChar;
// Return the old chunk, which is the suffix.
return Chunk;
}
#endif
};
} // end namespace clang

Просмотреть файл

@ -27,12 +27,7 @@ void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) {
assert(RealOffset+Size < Buffer.size() && "Invalid location");
// Remove the dead characters.
#ifdef USE_ROPE_VECTOR
RewriteRope::iterator I = Buffer.getAtOffset(RealOffset);
Buffer.erase(I, I+Size);
#else
Buffer.erase(RealOffset, Size);
#endif
// Add a delta so that future changes are offset correctly.
AddDelta(OrigOffset, -Size);
@ -46,15 +41,7 @@ void RewriteBuffer::InsertText(unsigned OrigOffset,
if (StrLen == 0) return;
unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
#ifdef USE_ROPE_VECTOR
assert(RealOffset <= Buffer.size() && "Invalid location");
// Insert the new characters.
Buffer.insert(Buffer.getAtOffset(RealOffset), StrData, StrData+StrLen);
#else
Buffer.insert(RealOffset, StrData, StrData+StrLen);
#endif
// Add a delta so that future changes are offset correctly.
AddDelta(OrigOffset, StrLen);
@ -66,30 +53,8 @@ void RewriteBuffer::InsertText(unsigned OrigOffset,
void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
const char *NewStr, unsigned NewLength) {
unsigned RealOffset = getMappedOffset(OrigOffset, true);
#ifdef USE_ROPE_VECTOR
assert(RealOffset+OrigLength <= Buffer.size() && "Invalid location");
// Overwrite the common piece.
unsigned CommonLength = std::min(OrigLength, NewLength);
std::copy(NewStr, NewStr+CommonLength, Buffer.getAtOffset(RealOffset));
// If replacing without shifting around, just overwrite the text.
if (OrigLength == NewLength)
return;
// If inserting more than existed before, this is like an insertion.
if (NewLength > OrigLength) {
Buffer.insert(Buffer.getAtOffset(RealOffset+OrigLength),
NewStr+OrigLength, NewStr+NewLength);
} else {
// If inserting less than existed before, this is like a removal.
RewriteRope::iterator I = Buffer.getAtOffset(RealOffset+NewLength);
Buffer.erase(I, I+(OrigLength-NewLength));
}
#else
Buffer.erase(RealOffset, OrigLength);
Buffer.insert(RealOffset, NewStr, NewStr+NewLength);
#endif
if (OrigLength != NewLength)
AddDelta(OrigOffset, NewLength-OrigLength);
}