]> git.lyx.org Git - features.git/blob - src/mathed/array.h
make doc++ able to generate the source documentation for lyx
[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 <string.h>
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         enum {
32                 ///
33                 ARRAY_SIZE = 256,
34                 ///
35                 ARRAY_STEP = 16,
36                 ///
37                 ARRAY_MIN_SIZE = 4
38         };
39
40         ///
41         explicit
42         LyxArrayBase(int size = ARRAY_STEP);
43         ///
44         LyxArrayBase(LyxArrayBase const &);
45         ///
46         ~LyxArrayBase();
47    
48         /// Constructs a new array with dx elements starting at pos 
49         LyxArrayBase & operator= (LyxArrayBase const &); 
50
51         ///
52         int empty() const { return (last == 0); }
53    
54         ///
55         int Last() { return last; }
56    
57         /// Fills with 0 the entire array and set last to 0
58         void Init();     
59    
60         /// Make the allocated memory fit the needed size
61         void Fit();     
62
63         /// Remove dx elements from position pos. Don't changes the size
64         void Remove(int pos, int dx);   
65
66         /// Merge dx elements from array a at pos. Changes the size if necessary.
67         void Merge(LyxArrayBase * a, int pos, int dx); 
68
69         /// Same as Merge but doesn't changes the size (dangerous)
70         void MergeF(LyxArrayBase * a, int pos, int dx); 
71
72         /// Copy dx byts from an array at position pos
73         void Copy(void *, int pos, int dx); 
74
75         /// Constructs a new array with dx elements starting at pos 
76         LyxArrayBase * Extract(int pos, int dx); 
77
78         /// Insert a character at position pos
79         void Insert(int pos, byte);
80
81         /// Insert a string of lenght dx at position pos
82         void Insert(int pos, byte *, int dx);
83
84         /// Constructs a new array with dx elements starting at pos 
85         byte operator[](const int);
86
87 protected:
88         ///
89         void Resize(int newsize);
90         ///
91         bool Move(int p, int shift);
92
93         /// Buffer
94         byte * bf;
95         /// Last position inserted.
96         int last;
97         /// Max size of the array.
98         int maxsize;
99 private:
100         ///
101         friend class MathedIter;
102 };
103    
104
105
106 /************************ Inline functions *****************************/
107
108 inline
109 void LyxArrayBase::Init()
110 {
111         memset(bf, 0, maxsize);
112         last = 0;
113 }
114
115 inline // Hmmm, Hp-UX's CC can't handle this inline. Asger.
116 void LyxArrayBase::Resize(int newsize)
117 {
118         if (newsize<ARRAY_MIN_SIZE)
119                 newsize = ARRAY_MIN_SIZE;
120         newsize += ARRAY_STEP - (newsize % ARRAY_STEP);
121         byte *nwbf = new byte[newsize];
122         if (last >= newsize) last = newsize-1;
123         maxsize = newsize;
124         memcpy(nwbf, bf, last);
125         delete[] bf;
126         bf = nwbf;
127         bf[last] = 0;
128 }
129
130 inline
131 LyxArrayBase::LyxArrayBase(int size) 
132 {
133         maxsize = (size<ARRAY_MIN_SIZE) ? ARRAY_MIN_SIZE: size;
134         bf = new byte[maxsize]; // this leaks
135         Init();
136 }
137
138 inline   
139 LyxArrayBase::~LyxArrayBase() 
140 {
141         delete[] bf;
142 }
143
144 inline
145 LyxArrayBase::LyxArrayBase(const LyxArrayBase& a) 
146 {
147         maxsize = a.maxsize;
148         bf = new byte[maxsize];
149         memcpy(&bf[0], &a.bf[0], maxsize);
150         last = a.last;
151 }
152
153 inline
154 LyxArrayBase& LyxArrayBase::operator= (const LyxArrayBase& a)
155 {
156         if (this != &a) {
157                 Resize(a.maxsize);
158                 memcpy(&bf[0], &a.bf[0], maxsize);
159         }
160         return *this;
161 }
162
163 inline   
164 bool LyxArrayBase::Move(int p, int shift) 
165 {
166         bool result = false;
167         if (p<= last) {
168                 if (last+shift>= maxsize) { 
169                     Resize(last + shift);
170                 }
171                 memmove(&bf[p+shift], &bf[p], last-p);
172                 last += shift;
173                 bf[last] = 0;
174                 result = true;
175         }
176         return result;
177 }
178
179 inline
180 void LyxArrayBase::Fit()
181 {
182         Resize(last);
183 }
184
185 inline
186 void LyxArrayBase::Remove(int pos, int dx)
187 {
188         Move(pos+dx, -dx);
189 }    
190
191 inline
192 void LyxArrayBase::Merge(LyxArrayBase *a, int p, int dx)
193 {
194         Move(p, dx);
195         memcpy(&bf[p], &a->bf[0], dx);
196 }
197  
198 inline
199 void LyxArrayBase::MergeF(LyxArrayBase *a, int p, int dx)
200 {
201         memcpy(&bf[p], &a->bf[0], dx);
202 }
203  
204 inline
205 void LyxArrayBase::Copy(void *a, int p, int dx)
206 {
207         memcpy(&bf[p], a, dx);
208 }
209
210 inline
211 LyxArrayBase *LyxArrayBase::Extract(int, int dx)
212 {
213         LyxArrayBase *a = new LyxArrayBase(dx);
214         a->Merge(this, 0, dx);
215         return a;
216 }
217  
218 inline
219 byte LyxArrayBase::operator[](const int i)
220 {
221         return bf[i];
222 }
223
224
225 inline
226 void LyxArrayBase::Insert(int pos, byte c)
227 {
228         if (pos<0) pos = last;
229         if (pos>= maxsize) 
230                 Resize(maxsize+ARRAY_STEP);
231         bf[pos] = c;
232         if (pos>= last)
233                 last = pos+1;
234 }