1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef CSV_VVECTOR_HXX
25 #define CSV_VVECTOR_HXX
26
27 #include <cstddef> // for ptrdiff_t
28
29 // USED SERVICES
30 #include <vector>
31 #include <cosv/tpl/tpltools.hxx>
32
33
34
35
36 namespace csv
37 {
38 namespace vvector
39 {
40
41
42 template <class TYPE>
43 struct delete_ptrs
44 {
Destructcsv::vvector::delete_ptrs45 static void Destruct(
46 std::vector< TYPE* > &
47 v)
48 { csv::erase_container_of_heap_ptrs(v); }
49
50 /// @precond ->it is a valid iterator within v
Erasecsv::vvector::delete_ptrs51 static void Erase(
52 std::vector< TYPE* > &
53 v,
54 typename std::vector< TYPE* >::iterator
55 it2erase )
56 { delete *it2erase; v.erase(it2erase); }
57
58 /// @precond ->v.size() > 0
PopBackcsv::vvector::delete_ptrs59 static void PopBack(
60 std::vector< TYPE* > &
61 v )
62 { delete v.back(); v.pop_back(); }
63
64 /// @precond ->it is a valid iterator
ReplacePtrcsv::vvector::delete_ptrs65 static void ReplacePtr(
66 typename std::vector< TYPE* >::iterator
67 it,
68 DYN TYPE * pass_new )
69 { delete *it; *it = pass_new; }
70 };
71
72
73 /** One helper class for the ->csv::VirtualVector.
74 Implements a
75 */
76 template <class TYPE>
77 struct keep_ptrs
78 {
Destructcsv::vvector::keep_ptrs79 static void Destruct(std::vector< TYPE* > & v)
80 {}
81
Erasecsv::vvector::keep_ptrs82 static void Erase(
83 std::vector< TYPE* > &
84 v,
85 typename std::vector< TYPE* >::iterator
86 it2erase )
87 { v.erase(it2erase); }
88
PopBackcsv::vvector::keep_ptrs89 static void PopBack(
90 std::vector< TYPE* > &
91 v )
92 { v.pop_back(); }
93
94 /// @precond ->it is a valid iterator
ReplacePtrcsv::vvector::keep_ptrs95 static void ReplacePtr(
96 typename std::vector< TYPE* >::iterator
97 it,
98 TYPE * io_new )
99 { *it = io_new; }
100 };
101
102
103 } // namespace vvector
104
105
106
107
108 /** Implements a vector of different implementations of a base
109 class.
110
111 Implementation has to be by pointers to get the polymorphic
112 behaviour, however access is by references to the base class.
113
114 @tpl XX
115 The common base class of vector elements.
116
117 @tpl PTRDEL
118 Has two possible values:
119 vvector::delete_ptrs<XX> Elements have to be on the heap and
120 are deleted when removed (default).
121 vvector::keep_ptrs<XX> Elements are only referenced and not
122 deleted when removed.
123
124 */
125 template <class XX, class PTRDEL = vvector::delete_ptrs<XX> >
126 class VirtualVector
127 {
128 public:
129 typedef VirtualVector<XX,PTRDEL> self;
130 typedef std::vector< DYN XX* > impl_type;
131 typedef typename impl_type::size_type size_type;
132 typedef ptrdiff_t difference_type;
133
134 class const_iterator;
135 class iterator;
136
137 // LIFECYCLE
138 VirtualVector();
139 explicit VirtualVector(
140 int i_size );
141 ~VirtualVector();
142
143 // OPERATORS
144 const XX & operator[](
145 size_type i_pos ) const;
146 XX & operator[](
147 size_type i_pos );
148
149 // OPERATIONS
150 void push_back(
151 DYN XX & i_drElement );
152 void pop_back();
153
154 iterator insert(
155 iterator i_pos,
156 DYN XX & i_drElement );
157 void erase(
158 iterator i_pos );
159 void replace(
160 iterator i_pos,
161 DYN XX & i_drElement );
162 void reserve(
163 size_type i_size );
164
165 // INQUIRY
166 bool empty() const;
167 size_t size() const;
168 const_iterator begin() const;
169 const_iterator end() const;
170 const XX & front() const;
171 const XX & back() const;
172
173 // ACCESS
174 iterator begin();
175 iterator end();
176 XX & front();
177 XX & back();
178
179 private:
180 // Forbidden:
181 VirtualVector(const VirtualVector&);
182 VirtualVector & operator=(const VirtualVector&);
183
184 // DATA
185 std::vector< DYN XX* >
186 aData;
187 };
188
189
190
191
192 /** Should be usable for all STL algorithms.
193 Implements the Random Access Iterator concept.
194 */
195 template <class XX, class PTRDEL>
196 class VirtualVector<XX,PTRDEL>::
197 const_iterator
198
199 // This derivation provides type information for the STL
200 // It introduces the types "value_type" and "difference_type".
201 : public std::iterator<std::random_access_iterator_tag,
202 const XX>
203 {
204 public:
205 typedef VirtualVector<XX,PTRDEL> my_container;
206 typedef typename my_container::impl_type::const_iterator impl_iterator;
207
208 // LIFECYCLE
const_iterator(impl_iterator i_implIter)209 const_iterator(
210 impl_iterator i_implIter )
211 : itImpl(i_implIter) {}
212
213
214 /////////// STL ITERATOR CONCEPT IMPLEMENTATION //////////////
215
216 // Default Constructible functions:
const_iterator()217 const_iterator()
218 : itImpl() {}
219
220 // Assignable functions:
221 // Assignment and copy constructor use the compiler generated versions.
222
223 // Equality Comparable functions:
operator ==(const_iterator i_other) const224 bool operator==(
225 const_iterator i_other ) const
226 { return itImpl == i_other.itImpl; }
operator !=(const_iterator i_other) const227 bool operator!=(
228 const_iterator i_other ) const
229 { return itImpl != i_other.itImpl; }
230
231 // Trivial Iterator functions:
operator *() const232 const XX & operator*() const
233 { return *(*itImpl); }
234
235 // Input Iterator functions:
operator ++()236 const_iterator & operator++()
237 { ++itImpl; return *this; }
operator ++(int)238 const_iterator operator++(int)
239 { return const_iterator(itImpl++); }
240
241 // Bidirectional Iterator functions:
operator --()242 const_iterator & operator--()
243 { --itImpl; return *this; }
operator --(int)244 const_iterator operator--(int)
245 { return const_iterator(itImpl--); }
246
247 // Less Than Comparable functions:
operator <(const_iterator i_other) const248 bool operator<(
249 const_iterator i_other ) const
250 { return itImpl < i_other.itImpl; }
251
252 // Random Access Iterator functions:
operator +=(difference_type i_diff)253 const_iterator & operator+=(
254 difference_type i_diff )
255 { itImpl += i_diff; return *this; }
operator +(difference_type i_diff) const256 const_iterator operator+(
257 difference_type i_diff ) const
258 { const_iterator ret(itImpl);
259 return ret += i_diff; }
operator -=(difference_type i_diff)260 const_iterator & operator-=(
261 difference_type i_diff )
262 { itImpl -= i_diff; return *this; }
operator -(difference_type i_diff) const263 const_iterator operator-(
264 difference_type i_diff ) const
265 { const_iterator ret(itImpl);
266 return ret -= i_diff; }
operator -(const_iterator i_it) const267 difference_type operator-(
268 const_iterator i_it ) const
269 { return itImpl - i_it.itImpl; }
operator [](difference_type i_index)270 const XX & operator[](
271 difference_type i_index )
272 { return *(*itImpl[i_index]); }
273
274 //////////////////////////////////////////////////////////////////////////
275
276 private:
277 friend class VirtualVector<XX,PTRDEL>;
ImplValue() const278 impl_iterator ImplValue() const { return itImpl; }
279
280 // DATA
281 impl_iterator itImpl;
282 };
283
284
285
286
287 /** Should be usable for all STL algorithms.
288 Implements the Random Access Iterator concept.
289 */
290 template <class XX, class PTRDEL>
291 class VirtualVector<XX,PTRDEL>::
292 iterator
293
294 // This derivation provides type information for the STL
295 // It introduces the types "value_type" and "difference_type".
296 : public std::iterator<std::random_access_iterator_tag,
297 XX>
298 {
299 public:
300 typedef VirtualVector<XX,PTRDEL> my_container;
301 typedef typename my_container::impl_type::iterator impl_iterator;
302
303 // LIFECYCLE
iterator(impl_iterator i_implIter)304 iterator(
305 impl_iterator i_implIter )
306 : itImpl(i_implIter) {}
307
308
309 /////////// STL ITERATOR CONCEPT IMPLEMENTATION //////////////
310
311 // Default Constructible functions:
iterator()312 iterator()
313 : itImpl() {}
314
315 // Assignable functions:
316 // Assignment and copy constructor use the compiler generated versions.
317
318 // Equality Comparable functions:
operator ==(iterator i_other) const319 bool operator==(
320 iterator i_other ) const
321 { return itImpl == i_other.itImpl; }
operator !=(iterator i_other) const322 bool operator!=(
323 iterator i_other ) const
324 { return itImpl != i_other.itImpl; }
325
326 // Trivial Iterator functions:
operator *() const327 XX & operator*() const
328 { return *(*itImpl); }
329
330 // Input Iterator functions:
operator ++()331 iterator & operator++()
332 { ++itImpl; return *this; }
operator ++(int)333 iterator operator++(int)
334 { return iterator(itImpl++); }
335
336 // Bidirectional Iterator functions:
operator --()337 iterator & operator--()
338 { --itImpl; return *this; }
operator --(int)339 iterator operator--(int)
340 { return iterator(itImpl--); }
341
342 // Less Than Comparable functions:
operator <(iterator i_other) const343 bool operator<(
344 iterator i_other ) const
345 { return itImpl < i_other.itImpl; }
346
347 // Random Access Iterator functions:
operator +=(difference_type i_diff)348 iterator & operator+=(
349 difference_type i_diff )
350 { itImpl += i_diff; return *this; }
operator +(difference_type i_diff) const351 iterator operator+(
352 difference_type i_diff ) const
353 { iterator ret(itImpl);
354 return ret += i_diff; }
operator -=(difference_type i_diff)355 iterator & operator-=(
356 difference_type i_diff )
357 { itImpl -= i_diff; return *this; }
operator -(difference_type i_diff) const358 iterator operator-(
359 difference_type i_diff ) const
360 { iterator ret(itImpl);
361 return ret -= i_diff; }
operator -(iterator i_it) const362 difference_type operator-(
363 iterator i_it ) const
364 { return itImpl - i_it.itImpl; }
operator [](difference_type i_index)365 XX & operator[](
366 difference_type i_index )
367 { return *(*itImpl[i_index]); }
368
369 //////////////////////////////////////////////////////////////////////////
370
371 private:
372 friend class VirtualVector<XX,PTRDEL>;
ImplValue() const373 impl_iterator ImplValue() const { return itImpl; }
374
375 // DATA
376 impl_iterator itImpl;
377 };
378
379
380
381
382 // IMPLEMENTATION
383 template <class XX, class PTRDEL>
384 inline
VirtualVector()385 VirtualVector<XX,PTRDEL>::VirtualVector()
386 : aData()
387 {
388 }
389
390 template <class XX, class PTRDEL>
391 inline
VirtualVector(int i_size)392 VirtualVector<XX,PTRDEL>::VirtualVector(int i_size)
393 : aData(i_size, 0)
394 {
395 }
396
397 template <class XX, class PTRDEL>
398 inline
~VirtualVector()399 VirtualVector<XX,PTRDEL>::~VirtualVector()
400 {
401 PTRDEL::Destruct(aData);
402 }
403
404 template <class XX, class PTRDEL>
405 inline const XX &
operator [](size_type i_pos) const406 VirtualVector<XX,PTRDEL>::operator[]( size_type i_pos ) const
407 {
408 return *aData[i_pos];
409 }
410
411 template <class XX, class PTRDEL>
412 inline XX &
operator [](size_type i_pos)413 VirtualVector<XX,PTRDEL>::operator[]( size_type i_pos )
414 {
415 return *aData[i_pos];
416 }
417
418 template <class XX, class PTRDEL>
419 inline void
push_back(DYN XX & i_drElement)420 VirtualVector<XX,PTRDEL>::push_back( DYN XX & i_drElement )
421 {
422 aData.push_back(&i_drElement);
423 }
424
425 template <class XX, class PTRDEL>
426 inline void
pop_back()427 VirtualVector<XX,PTRDEL>::pop_back()
428 {
429 if (NOT aData.empty())
430 PTRDEL::PopBack(aData);
431 }
432
433 template <class XX, class PTRDEL>
434 inline typename VirtualVector<XX,PTRDEL>::iterator
insert(iterator i_pos,DYN XX & i_drElement)435 VirtualVector<XX,PTRDEL>::insert( iterator i_pos,
436 DYN XX & i_drElement )
437 {
438 return iterator(aData.insert(i_pos.ImplValue(), &i_drElement));
439 }
440
441 template <class XX, class PTRDEL>
442 inline void
erase(iterator i_pos)443 VirtualVector<XX,PTRDEL>::erase( iterator i_pos )
444 {
445 PTRDEL::Erase(aData, i_pos.ImplValue());
446 }
447
448 template <class XX, class PTRDEL>
449 inline void
replace(iterator i_pos,DYN XX & i_drElement)450 VirtualVector<XX,PTRDEL>::replace( iterator i_pos,
451 DYN XX & i_drElement )
452 {
453 PTRDEL::ReplacePtr(*i_pos, &i_drElement);
454 }
455
456 template <class XX, class PTRDEL>
457 inline void
reserve(size_type i_size)458 VirtualVector<XX,PTRDEL>::reserve( size_type i_size )
459 {
460 aData.reserve(i_size);
461 }
462
463 template <class XX, class PTRDEL>
464 inline bool
empty() const465 VirtualVector<XX,PTRDEL>::empty() const
466 {
467 return aData.empty();
468 }
469
470 template <class XX, class PTRDEL>
471 inline size_t
size() const472 VirtualVector<XX,PTRDEL>::size() const
473 {
474 return aData.size();
475 }
476
477 template <class XX, class PTRDEL>
478 inline typename VirtualVector<XX,PTRDEL>::const_iterator
begin() const479 VirtualVector<XX,PTRDEL>::begin() const
480 {
481 return const_iterator(aData.begin());
482 }
483
484 template <class XX, class PTRDEL>
485 inline typename VirtualVector<XX,PTRDEL>::const_iterator
end() const486 VirtualVector<XX,PTRDEL>::end() const
487 {
488 return const_iterator(aData.end());
489 }
490
491 template <class XX, class PTRDEL>
492 inline const XX &
front() const493 VirtualVector<XX,PTRDEL>::front() const
494 {
495 return *aData.front();
496 }
497
498 template <class XX, class PTRDEL>
499 inline const XX &
back() const500 VirtualVector<XX,PTRDEL>::back() const
501 {
502 return *aData.back();
503 }
504
505 template <class XX, class PTRDEL>
506 inline typename VirtualVector<XX,PTRDEL>::iterator
begin()507 VirtualVector<XX,PTRDEL>::begin()
508 {
509 return iterator(aData.begin());
510 }
511
512 template <class XX, class PTRDEL>
513 inline typename VirtualVector<XX,PTRDEL>::iterator
end()514 VirtualVector<XX,PTRDEL>::end()
515 {
516 return iterator(aData.end());
517 }
518
519 template <class XX, class PTRDEL>
520 inline XX &
front()521 VirtualVector<XX,PTRDEL>::front()
522 {
523 return *aData.front();
524 }
525
526 template <class XX, class PTRDEL>
527 inline XX &
back()528 VirtualVector<XX,PTRDEL>::back()
529 {
530 return *aData.back();
531 }
532
533
534
535
536 } // namespace csv
537 #endif
538