xref: /AOO42X/main/soltools/inc/st_list.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SOLTOOLS_ST_LIST_HXX
29 #define SOLTOOLS_ST_LIST_HXX
30 
31 #include <string.h>
32 #include <iostream>
33 #include <stdlib.h>
34 
35 template <class XX>
36 class ST_List            /// Soltools-List.
37 {
38   public :
39     typedef XX *        iterator;
40     typedef const XX *  const_iterator;
41 
42     // LIFECYCLE
43                         ST_List();
44                         ST_List(
45                             const ST_List<XX> & i_rList );
46     virtual             ~ST_List() { }
47 
48     // OPERATORS
49     ST_List<XX> &       operator=(
50                             const ST_List<XX> & i_rList );
51 
52     const XX &          operator[](
53                             unsigned            n) const
54                                                 { return elem(n); }
55     XX &                operator[](
56                             unsigned            n)
57                                                 { return elem(n); }
58     // OPERATIONS
59     void                reserve(
60                             unsigned            i_nSize )
61                                                 { alloc(i_nSize,true); }
62     void                insert(
63                             iterator            i_aPos,
64                             const XX &          elem_ )
65                                                 { Insert(i_aPos-begin(), elem_); }
66     virtual void        Insert(
67                             unsigned            pos,
68                             const XX &          elem );
69     void                push_back(
70                             const XX &          elem_)
71                                                 { Insert(size(),elem_); }
72     void                remove(
73                             iterator            i_aPos )
74                                                 { Remove(i_aPos-begin()); }
75     virtual void        Remove(
76                             unsigned            pos );
77     void                pop_back()              { Remove(size()-1); }
78     void                erase_all()             { while (size()) Remove(size()-1); }
79 
80     // INQUIRY
81     const_iterator      begin() const           { return &inhalt[0]; }
82     const_iterator      end() const             { return &inhalt[len]; }
83 
84     const XX &          front() const           { return elem(0); }
85     const XX &          back() const            { return elem(len-1); }
86 
87     unsigned            size() const            { return len; }
88     unsigned            space() const           { return allocated; }
89     bool                is_valid_index(
90                             unsigned            n) const
91                                                 { return n < len; }
92     // ACCESS
93     iterator            begin()                 { return &inhalt[0]; }
94     iterator            end()                   { return &inhalt[len]; }
95 
96     XX &                front()                 { return elem(0); }
97     XX &                back()                  { return elem(len-1); }
98 
99   protected:
100     void                checkSize(
101                             unsigned            newLength);
102     void                alloc(
103                             unsigned            newSpace,
104                             bool                re = false );
105 
106     const XX &          elem(
107                             unsigned            n ) const
108                                                 { return inhalt[n]; }
109     XX &                elem(
110                             unsigned            n )
111                                                 { return inhalt[n]; }
112   // DATA
113     XX *                inhalt;
114     unsigned            len;
115     unsigned            allocated;
116 };
117 
118 
119 
120 template <class XY>
121 class DynamicList : public ST_List< XY* >
122 {
123   public:
124                         DynamicList();
125                         DynamicList(
126                             const DynamicList<XY> &
127                                                 i_rList );
128     virtual             ~DynamicList();         /// Deletes all member pointers
129 
130     DynamicList<XY> &   operator=(
131                             const DynamicList<XY> &
132                                                 i_rList );
133 
134     virtual void        Insert(
135                             unsigned            pos,
136                             XY * const &        elem );
137     virtual void        Remove(
138                             unsigned            pos );
139 };
140 
141 
142 
143 template <class XX>
144 ST_List<XX>::ST_List()
145     :   inhalt(0),
146         len(0),
147         allocated(0)
148 {
149     alloc(1);
150 }
151 
152 template <class XX>
153 ST_List<XX>::ST_List( const ST_List<XX> & i_rList )
154     :   inhalt(0),
155         len(0),
156         allocated(0)
157 {
158     alloc(i_rList.size());
159 
160     for ( const_iterator it = i_rList.begin();
161           it != i_rList.end();
162           ++it )
163     {
164         push_back(*it);
165     }
166 }
167 
168 template <class XX>
169 ST_List<XX> &
170 ST_List<XX>::operator=( const ST_List<XX> & i_rList )
171 {
172     for ( const_iterator it = i_rList.begin();
173           it != i_rList.end();
174           ++it )
175     {
176         push_back(*it);
177     }
178     return *this;
179 }
180 
181 template <class XX>
182 void
183 ST_List<XX>::Insert(unsigned pos, const XX & elem_)
184 {
185     if ( pos > len )
186       return;
187 
188     checkSize(len+2);
189     for ( unsigned p = len; p > pos; --p)
190     {
191         inhalt[p] = inhalt[p-1];
192     }
193     inhalt[pos] = elem_;
194     len++;
195 }
196 
197 
198 template <class XX>
199 void
200 ST_List<XX>::Remove(unsigned pos)
201 {
202     if ( pos >= len )
203       return;
204     len--;
205     for ( unsigned p = pos; p < len; ++p)
206     {
207         inhalt[p] = inhalt[p+1];
208     }
209 }
210 
211 
212 // Protected:
213 template <class XX>
214 void
215 ST_List<XX>::checkSize(unsigned newLength)
216 {
217    // neuen Platzbedarf pruefen:
218    unsigned newSpace = space();
219    if (newLength >= newSpace)
220    {
221       if (!newSpace)
222          newSpace = 1;
223       const unsigned nBorder = 2000000000;
224       while(newLength >= newSpace)
225       {
226         if (newSpace < nBorder)
227             newSpace <<= 1;
228         else
229         {
230             std::cerr << "List becomes too big" << std::endl;
231             exit(1);
232         }
233       }
234    }
235 
236    // Veraenderung ?:
237    if (newSpace != space())
238       alloc(newSpace,true);
239 }
240 
241 template <class XX>
242 void
243 ST_List<XX>::alloc( unsigned            newSpace,
244                     bool               re )
245 {
246     XX * pNew = new XX[newSpace];
247 
248     if (inhalt != 0)
249     {
250         if (re)
251         {
252             for (unsigned i = 0; i < len; ++i)
253             {
254                 pNew[i] = inhalt[i];
255             }  // end for
256         }
257         delete [] inhalt;
258     }
259 
260     inhalt = pNew;
261     allocated = newSpace;
262 }
263 
264 
265 template <class XY>
266 DynamicList<XY>::DynamicList()
267 {
268 }
269 
270 template <class XY>
271 DynamicList<XY>::DynamicList( const DynamicList<XY> & i_rList )
272     :   ST_List< XY* >(i_rList)
273 {
274     for ( typename DynamicList<XY>::iterator it = this->begin();
275           it != DynamicList<XY>::end();
276           ++it )
277     {
278         // Copying the contents the pointers point at:
279         (*it) = new XY( *(*it) );
280     }
281 }
282 
283 template <class XY>
284 DynamicList<XY>::~DynamicList()
285 {
286     this->erase_all();
287 }
288 
289 template <class XY>
290 DynamicList<XY> &
291 DynamicList<XY>::operator=( const DynamicList<XY> & i_rList )
292 {
293     for ( typename DynamicList<XY>::const_iterator it = i_rList.begin();
294           it != i_rList.end();
295           ++it )
296     {
297         push_back( new XY(*(*it)) );
298     }
299     return *this;
300 }
301 
302 
303 template <class XY>
304 void
305 DynamicList<XY>::Insert(unsigned pos, XY * const & elem_)
306 {
307     if ( pos > this->len )
308       return;
309 
310     checkSize(DynamicList<XY>::len+2);
311     memmove( DynamicList<XY>::inhalt+pos+1, DynamicList<XY>::inhalt+pos, (DynamicList<XY>::len-pos) * sizeof(XY*) );
312     this->inhalt[pos] = elem_;
313     this->len++;
314 }
315 
316 template <class XY>
317 void
318 DynamicList<XY>::Remove( unsigned pos )
319 {
320     if (!this->is_valid_index(pos) )
321         return;
322     this->len--;
323     delete DynamicList<XY>::inhalt[pos];
324     memmove(DynamicList<XY>::inhalt+pos, DynamicList<XY>::inhalt+pos+1, (DynamicList<XY>::len-pos) * sizeof(XY*) );
325 }
326 
327 
328 
329 #endif
330 
331