1 /*
2  * FTGL - OpenGL font library
3  *
4  * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifndef    __FTVector__
27 #define    __FTVector__
28 
29 #include "FTGL/ftgl.h"
30 
31 /**
32  * Provides a non-STL alternative to the STL vector
33  */
34 template <typename FT_VECTOR_ITEM_TYPE>
35 class FTVector
36 {
37     public:
38         typedef FT_VECTOR_ITEM_TYPE value_type;
39         typedef value_type& reference;
40         typedef const value_type& const_reference;
41         typedef value_type* iterator;
42         typedef const value_type* const_iterator;
43         typedef size_t size_type;
44 
FTVector()45         FTVector()
46         {
47             Capacity = Size = 0;
48             Items = 0;
49         }
50 
51 
~FTVector()52         virtual ~FTVector()
53         {
54             clear();
55         }
56 
57         FTVector& operator =(const FTVector& v)
58         {
59             reserve(v.capacity());
60 
61             iterator ptr = begin();
62             const_iterator vbegin = v.begin();
63             const_iterator vend = v.end();
64 
65             while(vbegin != vend)
66             {
67                 *ptr++ = *vbegin++;
68             }
69 
70             Size = v.size();
71             return *this;
72         }
73 
size()74         size_type size() const
75         {
76             return Size;
77         }
78 
capacity()79         size_type capacity() const
80         {
81             return Capacity;
82         }
83 
begin()84         iterator begin()
85         {
86             return Items;
87         }
88 
begin()89         const_iterator begin() const
90         {
91             return Items;
92         }
93 
end()94         iterator end()
95         {
96             return begin() + size();
97         }
98 
end()99         const_iterator end() const
100         {
101             return begin() + size();
102         }
103 
empty()104         bool empty() const
105         {
106             return size() == 0;
107         }
108 
109         reference operator [](size_type pos)
110         {
111             return(*(begin() + pos));
112         }
113 
114         const_reference operator [](size_type pos) const
115         {
116             return *(begin() + pos);
117         }
118 
clear()119         void clear()
120         {
121             if(Capacity)
122             {
123                 delete [] Items;
124                 Capacity = Size = 0;
125                 Items = 0;
126             }
127         }
128 
reserve(size_type n)129         void reserve(size_type n)
130         {
131             if(capacity() < n)
132             {
133                 expand(n);
134             }
135         }
136 
push_back(const value_type & x)137         void push_back(const value_type& x)
138         {
139             if(size() == capacity())
140             {
141                 expand();
142             }
143 
144            (*this)[size()] = x;
145             ++Size;
146         }
147 
resize(size_type n,value_type x)148         void resize(size_type n, value_type x)
149         {
150             if(n == size())
151             {
152                 return;
153             }
154 
155             reserve(n);
156             iterator ibegin, iend;
157 
158             if(n >= Size)
159             {
160                 ibegin = this->end();
161                 iend = this->begin() + n;
162             }
163             else
164             {
165                 ibegin = this->begin() + n;
166                 iend = this->end();
167             }
168 
169             while(ibegin != iend)
170             {
171                 *ibegin++ = x;
172             }
173 
174             Size = n;
175         }
176 
177 
178     private:
179         void expand(size_type capacity_hint = 0)
180         {
181             size_type new_capacity = (capacity() == 0) ? 256 : capacity() * 2;
182             if(capacity_hint)
183             {
184                 while(new_capacity < capacity_hint)
185                 {
186                     new_capacity *= 2;
187                 }
188             }
189 
190             value_type *new_items = new value_type[new_capacity];
191 
192             iterator ibegin = this->begin();
193             iterator iend = this->end();
194             value_type *ptr = new_items;
195 
196             while(ibegin != iend)
197             {
198                 *ptr++ = *ibegin++;
199             }
200 
201             if(Capacity)
202             {
203                 delete [] Items;
204             }
205 
206             Items = new_items;
207             Capacity = new_capacity;
208         }
209 
210         size_type Capacity;
211         size_type Size;
212         value_type* Items;
213 };
214 
215 #endif  //  __FTVector__
216