OSDN Git Service

Commit DialogBox compile Okay
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / SplitVector.h
diff --git a/ext/scintilla/src/SplitVector.h b/ext/scintilla/src/SplitVector.h
new file mode 100644 (file)
index 0000000..396fed2
--- /dev/null
@@ -0,0 +1,249 @@
+// Scintilla source code edit control\r
+/** @file SplitVector.h\r
+ ** Main data structure for holding arrays that handle insertions \r
+ ** and deletions efficiently.\r
+ **/\r
+// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>\r
+// The License.txt file describes the conditions under which this software may be distributed.\r
+\r
+#ifndef SPLITVECTOR_H\r
+#define SPLITVECTOR_H\r
+\r
+template <typename T>\r
+class SplitVector {\r
+protected:\r
+       T *body;\r
+       int size;\r
+       int lengthBody;\r
+       int part1Length;\r
+       int gapLength;  /// invariant: gapLength == size - lengthBody\r
+       int growSize;\r
+\r
+       /// Move the gap to a particular position so that insertion and\r
+       /// deletion at that point will not require much copying and\r
+       /// hence be fast.\r
+       void GapTo(int position) {\r
+               if (position != part1Length) {\r
+                       if (position < part1Length) {\r
+                               memmove(\r
+                                       body + position + gapLength,\r
+                                       body + position,\r
+                                       sizeof(T) * (part1Length - position));\r
+                       } else {        // position > part1Length\r
+                               memmove(\r
+                                       body + part1Length,\r
+                                       body + part1Length + gapLength,\r
+                                       sizeof(T) * (position - part1Length));\r
+                       }\r
+                       part1Length = position;\r
+               }\r
+       }\r
+\r
+       /// Check that there is room in the buffer for an insertion,\r
+       /// reallocating if more space needed.\r
+       void RoomFor(int insertionLength) {\r
+               if (gapLength <= insertionLength) {\r
+                       if (growSize * 6 < size)\r
+                               growSize *= 2;\r
+                       ReAllocate(size + insertionLength + growSize);\r
+               }\r
+       }\r
+\r
+       void Init() {\r
+               body = NULL;\r
+               growSize = 8;\r
+               size = 0;\r
+               lengthBody = 0;\r
+               part1Length = 0;\r
+               gapLength = 0;\r
+       }\r
+\r
+public:\r
+       /// Construct a split buffer.\r
+       SplitVector() {\r
+               Init();\r
+       }\r
+\r
+       ~SplitVector() {\r
+               delete []body;\r
+               body = 0;\r
+       }\r
+\r
+       int GetGrowSize() const {\r
+               return growSize;\r
+       }\r
+\r
+       void SetGrowSize(int growSize_) {\r
+               growSize = growSize_;\r
+       }\r
+\r
+       /// Reallocate the storage for the buffer to be newSize and\r
+       /// copy exisiting contents to the new buffer.\r
+       /// Must not be used to decrease the size of the buffer.\r
+       void ReAllocate(int newSize) {\r
+               if (newSize > size) {\r
+                       // Move the gap to the end\r
+                       GapTo(lengthBody);\r
+                       T *newBody = new T[newSize];\r
+                       if ((size != 0) && (body != 0)) {\r
+                               memmove(newBody, body, sizeof(T) * lengthBody);\r
+                               delete []body;\r
+                       }\r
+                       body = newBody;\r
+                       gapLength += newSize - size;\r
+                       size = newSize;\r
+               }\r
+       }\r
+\r
+       /// Retrieve the character at a particular position.\r
+       /// Retrieving positions outside the range of the buffer returns 0.\r
+       /// The assertions here are disabled since calling code can be \r
+       /// simpler if out of range access works and returns 0.\r
+       T ValueAt(int position) const {\r
+               if (position < part1Length) {\r
+                       //PLATFORM_ASSERT(position >= 0);\r
+                       if (position < 0) {\r
+                               return 0;\r
+                       } else {\r
+                               return body[position];\r
+                       }\r
+               } else {\r
+                       //PLATFORM_ASSERT(position < lengthBody);\r
+                       if (position >= lengthBody) {\r
+                               return 0;\r
+                       } else {\r
+                               return body[gapLength + position];\r
+                       }\r
+               }\r
+       }\r
+\r
+       void SetValueAt(int position, T v) {\r
+               if (position < part1Length) {\r
+                       PLATFORM_ASSERT(position >= 0);\r
+                       if (position < 0) {\r
+                               ;\r
+                       } else {\r
+                               body[position] = v;\r
+                       }\r
+               } else {\r
+                       PLATFORM_ASSERT(position < lengthBody);\r
+                       if (position >= lengthBody) {\r
+                               ;\r
+                       } else {\r
+                               body[gapLength + position] = v;\r
+                       }\r
+               }\r
+       }\r
+\r
+       T& operator[](int position) const {\r
+               PLATFORM_ASSERT(position >= 0 && position < lengthBody);\r
+               if (position < part1Length) {\r
+                       return body[position];\r
+               } else {\r
+                       return body[gapLength + position];\r
+               }\r
+       }\r
+\r
+       /// Retrieve the length of the buffer.\r
+       int Length() const {\r
+               return lengthBody;\r
+       }\r
+\r
+       /// Insert a single value into the buffer.\r
+       /// Inserting at positions outside the current range fails.\r
+       void Insert(int position, T v) {\r
+               PLATFORM_ASSERT((position >= 0) && (position <= lengthBody));\r
+               if ((position < 0) || (position > lengthBody)) {\r
+                       return;\r
+               }\r
+               RoomFor(1);\r
+               GapTo(position);\r
+               body[part1Length] = v;\r
+               lengthBody++;\r
+               part1Length++;\r
+               gapLength--;\r
+       }\r
+\r
+       /// Insert a number of elements into the buffer setting their value.\r
+       /// Inserting at positions outside the current range fails.\r
+       void InsertValue(int position, int insertLength, T v) {\r
+               PLATFORM_ASSERT((position >= 0) && (position <= lengthBody));\r
+               if (insertLength > 0) {\r
+                       if ((position < 0) || (position > lengthBody)) {\r
+                               return;\r
+                       }\r
+                       RoomFor(insertLength);\r
+                       GapTo(position);\r
+                       for (int i = 0; i < insertLength; i++)\r
+                               body[part1Length + i] = v;\r
+                       lengthBody += insertLength;\r
+                       part1Length += insertLength;\r
+                       gapLength -= insertLength;\r
+               }\r
+       }\r
+\r
+       /// Ensure at least length elements allocated, \r
+       /// appending zero valued elements if needed.\r
+       void EnsureLength(int wantedLength) {\r
+               if (Length() < wantedLength) {\r
+                       InsertValue(Length(), wantedLength - Length(), 0);\r
+               }\r
+       }\r
+       \r
+       /// Insert text into the buffer from an array.\r
+       void InsertFromArray(int positionToInsert, const T s[], int positionFrom, int insertLength) {\r
+               PLATFORM_ASSERT((positionToInsert >= 0) && (positionToInsert <= lengthBody));\r
+               if (insertLength > 0) {\r
+                       if ((positionToInsert < 0) || (positionToInsert > lengthBody)) {\r
+                               return;\r
+                       }\r
+                       RoomFor(insertLength);\r
+                       GapTo(positionToInsert);\r
+                       memmove(body + part1Length, s + positionFrom, sizeof(T) * insertLength);\r
+                       lengthBody += insertLength;\r
+                       part1Length += insertLength;\r
+                       gapLength -= insertLength;\r
+               }\r
+       }\r
+\r
+       /// Delete one element from the buffer.\r
+       void Delete(int position) {\r
+               PLATFORM_ASSERT((position >= 0) && (position < lengthBody));\r
+               if ((position < 0) || (position >= lengthBody)) {\r
+                       return;\r
+               }\r
+               DeleteRange(position, 1);\r
+       }\r
+\r
+       /// Delete a range from the buffer.\r
+       /// Deleting positions outside the current range fails.\r
+       void DeleteRange(int position, int deleteLength) {\r
+               PLATFORM_ASSERT((position >= 0) && (position + deleteLength <= lengthBody));\r
+               if ((position < 0) || ((position + deleteLength) > lengthBody)) {\r
+                       return;\r
+               }\r
+               if ((position == 0) && (deleteLength == lengthBody)) {\r
+                       // Full deallocation returns storage and is faster\r
+                       delete []body;\r
+                       Init();\r
+               } else if (deleteLength > 0) {\r
+                       GapTo(position);\r
+                       lengthBody -= deleteLength;\r
+                       gapLength += deleteLength;\r
+               }\r
+       }\r
+\r
+       /// Delete all the buffer contents.\r
+       void DeleteAll() {\r
+               DeleteRange(0, lengthBody);\r
+       }\r
+\r
+       T* BufferPointer() {\r
+               RoomFor(1);\r
+               GapTo(lengthBody);\r
+               body[lengthBody] = 0;\r
+               return body;\r
+       }\r
+};\r
+\r
+#endif\r