]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/SplitVector.h
1 // Scintilla source code edit control
2 /** @file SplitVector.h
3 ** Main data structure for holding arrays that handle insertions
4 ** and deletions efficiently.
6 // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
19 int gapLength
; /// invariant: gapLength == size - lengthBody
22 /// Move the gap to a particular position so that insertion and
23 /// deletion at that point will not require much copying and
25 void GapTo(int position
) {
26 if (position
!= part1Length
) {
27 if (position
< part1Length
) {
29 body
+ position
+ gapLength
,
31 sizeof(T
) * (part1Length
- position
));
32 } else { // position > part1Length
35 body
+ part1Length
+ gapLength
,
36 sizeof(T
) * (position
- part1Length
));
38 part1Length
= position
;
42 /// Check that there is room in the buffer for an insertion,
43 /// reallocating if more space needed.
44 void RoomFor(int insertionLength
) {
45 if (gapLength
<= insertionLength
) {
46 if (growSize
* 6 < size
)
48 ReAllocate(size
+ insertionLength
+ growSize
);
62 /// Construct a split buffer.
72 int GetGrowSize() const {
76 void SetGrowSize(int growSize_
) {
80 /// Reallocate the storage for the buffer to be newSize and
81 /// copy exisiting contents to the new buffer.
82 /// Must not be used to decrease the size of the buffer.
83 void ReAllocate(int newSize
) {
85 // Move the gap to the end
87 T
*newBody
= new T
[newSize
];
88 if ((size
!= 0) && (body
!= 0)) {
89 memmove(newBody
, body
, sizeof(T
) * lengthBody
);
93 gapLength
+= newSize
- size
;
98 /// Retrieve the character at a particular position.
99 /// Retrieving positions outside the range of the buffer returns 0.
100 /// The assertions here are disabled since calling code can be
101 /// simpler if out of range access works and returns 0.
102 T
ValueAt(int position
) const {
103 if (position
< part1Length
) {
104 //PLATFORM_ASSERT(position >= 0);
108 return body
[position
];
111 //PLATFORM_ASSERT(position < lengthBody);
112 if (position
>= lengthBody
) {
115 return body
[gapLength
+ position
];
120 void SetValueAt(int position
, T v
) {
121 if (position
< part1Length
) {
122 PLATFORM_ASSERT(position
>= 0);
129 PLATFORM_ASSERT(position
< lengthBody
);
130 if (position
>= lengthBody
) {
133 body
[gapLength
+ position
] = v
;
138 T
& operator[](int position
) const {
139 PLATFORM_ASSERT(position
>= 0 && position
< lengthBody
);
140 if (position
< part1Length
) {
141 return body
[position
];
143 return body
[gapLength
+ position
];
147 /// Retrieve the length of the buffer.
152 /// Insert a single value into the buffer.
153 /// Inserting at positions outside the current range fails.
154 void Insert(int position
, T v
) {
155 PLATFORM_ASSERT((position
>= 0) && (position
<= lengthBody
));
156 if ((position
< 0) || (position
> lengthBody
)) {
161 body
[part1Length
] = v
;
167 /// Insert a number of elements into the buffer setting their value.
168 /// Inserting at positions outside the current range fails.
169 void InsertValue(int position
, int insertLength
, T v
) {
170 PLATFORM_ASSERT((position
>= 0) && (position
<= lengthBody
));
171 if (insertLength
> 0) {
172 if ((position
< 0) || (position
> lengthBody
)) {
175 RoomFor(insertLength
);
177 for (int i
= 0; i
< insertLength
; i
++)
178 body
[part1Length
+ i
] = v
;
179 lengthBody
+= insertLength
;
180 part1Length
+= insertLength
;
181 gapLength
-= insertLength
;
185 /// Ensure at least length elements allocated,
186 /// appending zero valued elements if needed.
187 void EnsureLength(int wantedLength
) {
188 if (Length() < wantedLength
) {
189 InsertValue(Length(), wantedLength
- Length(), 0);
193 /// Insert text into the buffer from an array.
194 void InsertFromArray(int positionToInsert
, const T s
[], int positionFrom
, int insertLength
) {
195 PLATFORM_ASSERT((positionToInsert
>= 0) && (positionToInsert
<= lengthBody
));
196 if (insertLength
> 0) {
197 if ((positionToInsert
< 0) || (positionToInsert
> lengthBody
)) {
200 RoomFor(insertLength
);
201 GapTo(positionToInsert
);
202 memmove(body
+ part1Length
, s
+ positionFrom
, sizeof(T
) * insertLength
);
203 lengthBody
+= insertLength
;
204 part1Length
+= insertLength
;
205 gapLength
-= insertLength
;
209 /// Delete one element from the buffer.
210 void Delete(int position
) {
211 PLATFORM_ASSERT((position
>= 0) && (position
< lengthBody
));
212 if ((position
< 0) || (position
>= lengthBody
)) {
215 DeleteRange(position
, 1);
218 /// Delete a range from the buffer.
219 /// Deleting positions outside the current range fails.
220 void DeleteRange(int position
, int deleteLength
) {
221 PLATFORM_ASSERT((position
>= 0) && (position
+ deleteLength
<= lengthBody
));
222 if ((position
< 0) || ((position
+ deleteLength
) > lengthBody
)) {
225 if ((position
== 0) && (deleteLength
== lengthBody
)) {
226 // Full deallocation returns storage and is faster
229 } else if (deleteLength
> 0) {
231 lengthBody
-= deleteLength
;
232 gapLength
+= deleteLength
;
236 /// Delete all the buffer contents.
238 DeleteRange(0, lengthBody
);