LLVM 22.0.0git
RewriteRope.h
Go to the documentation of this file.
1//===- RewriteRope.h - Rope specialized for rewriter ------------*- 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// This file defines the RewriteRope class, which is a powerful string class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_ADT_REWRITEROPE_H
14#define LLVM_ADT_REWRITEROPE_H
15
17#include "llvm/ADT/StringRef.h"
19#include <cassert>
20#include <cstddef>
21#include <iterator>
22#include <utility>
23
24namespace llvm {
25
26//===--------------------------------------------------------------------===//
27// RopeRefCountString Class
28//===--------------------------------------------------------------------===//
29
30/// RopeRefCountString - This struct is allocated with 'new char[]' from the
31/// heap, and represents a reference counted chunk of string data. When its
32/// ref count drops to zero, it is delete[]'d. This is primarily managed
33/// through the RopePiece class below.
35 unsigned RefCount;
36 char Data[1]; // Variable sized.
37
38 void Retain() { ++RefCount; }
39
40 void Release() {
41 assert(RefCount > 0 && "Reference count is already zero.");
42 if (--RefCount == 0)
43 delete[] (char *)this;
44 }
45};
46
47//===--------------------------------------------------------------------===//
48// RopePiece Class
49//===--------------------------------------------------------------------===//
50
51/// RopePiece - This class represents a view into a RopeRefCountString object.
52/// This allows references to string data to be efficiently chopped up and
53/// moved around without having to push around the string data itself.
54///
55/// For example, we could have a 1M RopePiece and want to insert something
56/// into the middle of it. To do this, we split it into two RopePiece objects
57/// that both refer to the same underlying RopeRefCountString (just with
58/// different offsets) which is a nice constant time operation.
59struct RopePiece {
61 unsigned StartOffs = 0;
62 unsigned EndOffs = 0;
63
64 RopePiece() = default;
66 unsigned End)
67 : StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
68
69 const char &operator[](unsigned Offset) const {
70 return StrData->Data[Offset + StartOffs];
71 }
72 char &operator[](unsigned Offset) {
73 return StrData->Data[Offset + StartOffs];
74 }
75
76 unsigned size() const { return EndOffs - StartOffs; }
77};
78
79//===--------------------------------------------------------------------===//
80// RopePieceBTreeIterator Class
81//===--------------------------------------------------------------------===//
82
83/// RopePieceBTreeIterator - This class provides read-only forward iteration
84/// over bytes that are in a RopePieceBTree. This first iterates over bytes
85/// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
86/// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
88 /// CurNode - The current B+Tree node that we are inspecting.
89 const void /*RopePieceBTreeLeaf*/ *CurNode = nullptr;
90
91 /// CurPiece - The current RopePiece in the B+Tree node that we're
92 /// inspecting.
93 const RopePiece *CurPiece = nullptr;
94
95 /// CurChar - The current byte in the RopePiece we are pointing to.
96 unsigned CurChar = 0;
97
98public:
99 using iterator_category = std::forward_iterator_tag;
100 using value_type = const char;
101 using difference_type = std::ptrdiff_t;
104
106 LLVM_ABI RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
107
108 char operator*() const { return (*CurPiece)[CurChar]; }
109
111 return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
112 }
114 return !operator==(RHS);
115 }
116
118 if (CurChar + 1 < CurPiece->size())
119 ++CurChar;
120 else
122 return *this;
123 }
124
125 RopePieceBTreeIterator operator++(int) { // Postincrement
126 RopePieceBTreeIterator tmp = *this;
127 ++*this;
128 return tmp;
129 }
130
132 return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
133 }
134
136};
137
138//===--------------------------------------------------------------------===//
139// RopePieceBTree Class
140//===--------------------------------------------------------------------===//
141
143 void /*RopePieceBTreeNode*/ *Root;
144
145public:
150
152
153 iterator begin() const { return iterator(Root); }
154 iterator end() const { return iterator(); }
155 LLVM_ABI unsigned size() const;
156 unsigned empty() const { return size() == 0; }
157
158 LLVM_ABI void clear();
159
160 LLVM_ABI void insert(unsigned Offset, const RopePiece &R);
161
162 LLVM_ABI void erase(unsigned Offset, unsigned NumBytes);
163};
164
165//===--------------------------------------------------------------------===//
166// RewriteRope Class
167//===--------------------------------------------------------------------===//
168
169/// RewriteRope - A powerful string class. This class supports extremely
170/// efficient insertions and deletions into the middle of it, even for
171/// ridiculously long strings.
173 RopePieceBTree Chunks;
174
175 /// We allocate space for string data out of a buffer of size AllocChunkSize.
176 /// This keeps track of how much space is left.
178 enum { AllocChunkSize = 4080 };
179 unsigned AllocOffs = AllocChunkSize;
180
181public:
182 RewriteRope() = default;
183 RewriteRope(const RewriteRope &RHS) : Chunks(RHS.Chunks) {}
184
185 // The copy assignment operator is defined as deleted pending further
186 // motivation.
188
191
192 iterator begin() const { return Chunks.begin(); }
193 iterator end() const { return Chunks.end(); }
194 unsigned size() const { return Chunks.size(); }
195
196 void clear() { Chunks.clear(); }
197
198 void assign(const char *Start, const char *End) {
199 clear();
200 if (Start != End)
201 Chunks.insert(0, MakeRopeString(Start, End));
202 }
203
204 void insert(unsigned Offset, const char *Start, const char *End) {
205 assert(Offset <= size() && "Invalid position to insert!");
206 if (Start == End)
207 return;
208 Chunks.insert(Offset, MakeRopeString(Start, End));
209 }
210
211 void erase(unsigned Offset, unsigned NumBytes) {
212 assert(Offset + NumBytes <= size() && "Invalid region to erase!");
213 if (NumBytes == 0)
214 return;
215 Chunks.erase(Offset, NumBytes);
216 }
217
218private:
219 LLVM_ABI RopePiece MakeRopeString(const char *Start, const char *End);
220};
221
222} // namespace llvm
223
224#endif // LLVM_ADT_REWRITEROPE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:213
This file defines the RefCountedBase, ThreadSafeRefCountedBase, and IntrusiveRefCntPtr classes.
Value * RHS
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
RewriteRope()=default
unsigned size() const
RewriteRope & operator=(const RewriteRope &)=delete
void insert(unsigned Offset, const char *Start, const char *End)
RopePieceBTree::iterator iterator
iterator end() const
RewriteRope(const RewriteRope &RHS)
RopePieceBTree::iterator const_iterator
void erase(unsigned Offset, unsigned NumBytes)
iterator begin() const
void assign(const char *Start, const char *End)
RopePieceBTreeIterator - This class provides read-only forward iteration over bytes that are in a Rop...
Definition RewriteRope.h:87
RopePieceBTreeIterator & operator++()
bool operator==(const RopePieceBTreeIterator &RHS) const
std::forward_iterator_tag iterator_category
Definition RewriteRope.h:99
RopePieceBTreeIterator operator++(int)
llvm::StringRef piece() const
bool operator!=(const RopePieceBTreeIterator &RHS) const
iterator end() const
LLVM_ABI unsigned size() const
RopePieceBTreeIterator iterator
LLVM_ABI void insert(unsigned Offset, const RopePiece &R)
LLVM_ABI void erase(unsigned Offset, unsigned NumBytes)
iterator begin() const
RopePieceBTree & operator=(const RopePieceBTree &)=delete
LLVM_ABI void clear()
unsigned empty() const
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1847
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:851
#define N
RopePiece - This class represents a view into a RopeRefCountString object.
Definition RewriteRope.h:59
unsigned EndOffs
Definition RewriteRope.h:62
RopePiece()=default
unsigned StartOffs
Definition RewriteRope.h:61
char & operator[](unsigned Offset)
Definition RewriteRope.h:72
RopePiece(llvm::IntrusiveRefCntPtr< RopeRefCountString > Str, unsigned Start, unsigned End)
Definition RewriteRope.h:65
unsigned size() const
Definition RewriteRope.h:76
const char & operator[](unsigned Offset) const
Definition RewriteRope.h:69
llvm::IntrusiveRefCntPtr< RopeRefCountString > StrData
Definition RewriteRope.h:60
RopeRefCountString - This struct is allocated with 'new char[]' from the heap, and represents a refer...
Definition RewriteRope.h:34