]> git.lyx.org Git - features.git/blob - src/mathed/array.h
9f9bdd36f09111c042d31b486ef9737a48177e71
[features.git] / src / mathed / array.h
1 // -*- C++ -*-
2 /*
3  *  File:        array.h
4  *  Purpose:     A general purpose resizable array.  
5  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
6  *  Created:     January 1996
7  *
8  *  Dependencies: None (almost)
9  *
10  *  Copyright: 1996, Alejandro Aguilar Sierra
11  *                 1997  The LyX Team!
12  *
13  *   You are free to use and modify this code under the terms of
14  *   the GNU General Public Licence version 2 or later.
15  */
16
17 #include <vector>
18
19 #ifndef byte
20 #define byte unsigned char
21 #endif
22
23 /** A resizable array.
24     A general purpose resizable array.
25     @author Alejandro Aguilar Sierra
26     @version January 1996
27   */
28 class LyxArrayBase  {
29 public:
30         ///
31         typedef std::vector<byte> buffer_type;
32         ///
33         enum {
34                 ///
35                 ARRAY_SIZE = 256,
36                 ///
37                 ARRAY_STEP = 16,
38                 ///
39                 ARRAY_MIN_SIZE = 4
40         };
41
42         ///
43         explicit
44         LyxArrayBase(int size = ARRAY_STEP);
45
46         ///
47         int empty() const { return (last == 0); }
48    
49         ///
50         int Last() { return last; }
51    
52         /// Make the allocated memory fit the needed size
53         void Fit();     
54
55         /// Remove dx elements from position pos. Don't changes the size
56         void Remove(int pos, int dx);   
57
58         /// Merge dx elements from array a at pos. Changes the size if necessary.
59         void Merge(LyxArrayBase * a, int pos, int dx); 
60
61         /// Same as Merge but doesn't changes the size (dangerous)
62         void MergeF(LyxArrayBase * a, int pos, int dx); 
63
64         /// Copy dx byts from an array at position pos
65         void Copy(void *, int pos, int dx); 
66
67         /// Constructs a new array with dx elements starting at pos 
68         LyxArrayBase * Extract(int pos, int dx); 
69
70         /// Insert a character at position pos
71         void Insert(int pos, byte);
72
73         /// Constructs a new array with dx elements starting at pos 
74         byte operator[](const int);
75
76 protected:
77         ///
78         void Resize(int newsize);
79         ///
80         bool Move(int p, int shift);
81
82         /// Buffer
83         buffer_type bf;
84         /// Last position inserted.
85         int last;
86         /// Max size of the array.
87         int maxsize;
88 private:
89         ///
90         friend class MathedIter;
91 };
92    
93
94
95 /************************ Inline functions *****************************/
96
97 inline // Hmmm, Hp-UX's CC can't handle this inline. Asger.
98 void LyxArrayBase::Resize(int newsize)
99 {
100         if (newsize<ARRAY_MIN_SIZE)
101                 newsize = ARRAY_MIN_SIZE;
102         newsize += ARRAY_STEP - (newsize % ARRAY_STEP);
103         bf.resize(newsize);
104         if (last >= newsize) last = newsize-1;
105         maxsize = newsize;
106         bf[last] = 0;
107 }
108
109 inline
110 LyxArrayBase::LyxArrayBase(int size) 
111 {
112         maxsize = (size<ARRAY_MIN_SIZE) ? ARRAY_MIN_SIZE: size;
113         bf.resize(maxsize);
114         last = 0;
115 }
116
117 inline   
118 bool LyxArrayBase::Move(int p, int shift) 
119 {
120         bool result = false;
121         if (p <= last) {
122                 if (last + shift >= maxsize) { 
123                     Resize(last + shift);
124                 }
125                 memmove(&bf[p + shift], &bf[p], last - p);
126                 last += shift;
127                 bf[last] = 0;
128                 result = true;
129         }
130         return result;
131 }
132
133 inline
134 void LyxArrayBase::Fit()
135 {
136         Resize(last);
137 }
138
139 inline
140 void LyxArrayBase::Remove(int pos, int dx)
141 {
142         Move(pos + dx, -dx);
143 }    
144
145 inline
146 void LyxArrayBase::Merge(LyxArrayBase * a, int p, int dx)
147 {
148         Move(p, dx);
149         memcpy(&bf[p], &a->bf[0], dx);
150 }
151  
152 inline
153 void LyxArrayBase::MergeF(LyxArrayBase * a, int p, int dx)
154 {
155         memcpy(&bf[p], &a->bf[0], dx);
156 }
157  
158 inline
159 void LyxArrayBase::Copy(void * a, int p, int dx)
160 {
161         memcpy(&bf[p], a, dx);
162 }
163
164 inline
165 LyxArrayBase * LyxArrayBase::Extract(int, int dx)
166 {
167         LyxArrayBase * a = new LyxArrayBase(dx);
168         a->Merge(this, 0, dx);
169         return a;
170 }
171  
172 inline
173 byte LyxArrayBase::operator[](const int i)
174 {
175         return bf[i];
176 }
177
178
179 inline
180 void LyxArrayBase::Insert(int pos, byte c)
181 {
182         if (pos < 0) pos = last;
183         if (pos >= maxsize) 
184                 Resize(maxsize + ARRAY_STEP);
185         bf[pos] = c;
186         if (pos >= last)
187                 last = pos + 1;
188 }