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 { 45 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 51 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 59 static void PopBack( 60 std::vector< TYPE* > & 61 v ) 62 { delete v.back(); v.pop_back(); } 63 64 /// @precond ->it is a valid iterator 65 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 { 79 static void Destruct(std::vector< TYPE* > & v) 80 {} 81 82 static void Erase( 83 std::vector< TYPE* > & 84 v, 85 typename std::vector< TYPE* >::iterator 86 it2erase ) 87 { v.erase(it2erase); } 88 89 static void PopBack( 90 std::vector< TYPE* > & 91 v ) 92 { v.pop_back(); } 93 94 /// @precond ->it is a valid iterator 95 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 209 const_iterator( 210 impl_iterator i_implIter ) 211 : itImpl(i_implIter) {} 212 213 214 /////////// STL ITERATOR CONCEPT IMPLEMENTATION ////////////// 215 216 // Default Constructible functions: 217 const_iterator() 218 : itImpl() {} 219 220 // Assignable functions: 221 // Assignment and copy constructor use the compiler generated versions. 222 223 // Equality Comparable functions: 224 bool operator==( 225 const_iterator i_other ) const 226 { return itImpl == i_other.itImpl; } 227 bool operator!=( 228 const_iterator i_other ) const 229 { return itImpl != i_other.itImpl; } 230 231 // Trivial Iterator functions: 232 const XX & operator*() const 233 { return *(*itImpl); } 234 235 // Input Iterator functions: 236 const_iterator & operator++() 237 { ++itImpl; return *this; } 238 const_iterator operator++(int) 239 { return const_iterator(itImpl++); } 240 241 // Bidirectional Iterator functions: 242 const_iterator & operator--() 243 { --itImpl; return *this; } 244 const_iterator operator--(int) 245 { return const_iterator(itImpl--); } 246 247 // Less Than Comparable functions: 248 bool operator<( 249 const_iterator i_other ) const 250 { return itImpl < i_other.itImpl; } 251 252 // Random Access Iterator functions: 253 const_iterator & operator+=( 254 difference_type i_diff ) 255 { itImpl += i_diff; return *this; } 256 const_iterator operator+( 257 difference_type i_diff ) const 258 { const_iterator ret(itImpl); 259 return ret += i_diff; } 260 const_iterator & operator-=( 261 difference_type i_diff ) 262 { itImpl -= i_diff; return *this; } 263 const_iterator operator-( 264 difference_type i_diff ) const 265 { const_iterator ret(itImpl); 266 return ret -= i_diff; } 267 difference_type operator-( 268 const_iterator i_it ) const 269 { return itImpl - i_it.itImpl; } 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>; 278 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 304 iterator( 305 impl_iterator i_implIter ) 306 : itImpl(i_implIter) {} 307 308 309 /////////// STL ITERATOR CONCEPT IMPLEMENTATION ////////////// 310 311 // Default Constructible functions: 312 iterator() 313 : itImpl() {} 314 315 // Assignable functions: 316 // Assignment and copy constructor use the compiler generated versions. 317 318 // Equality Comparable functions: 319 bool operator==( 320 iterator i_other ) const 321 { return itImpl == i_other.itImpl; } 322 bool operator!=( 323 iterator i_other ) const 324 { return itImpl != i_other.itImpl; } 325 326 // Trivial Iterator functions: 327 XX & operator*() const 328 { return *(*itImpl); } 329 330 // Input Iterator functions: 331 iterator & operator++() 332 { ++itImpl; return *this; } 333 iterator operator++(int) 334 { return iterator(itImpl++); } 335 336 // Bidirectional Iterator functions: 337 iterator & operator--() 338 { --itImpl; return *this; } 339 iterator operator--(int) 340 { return iterator(itImpl--); } 341 342 // Less Than Comparable functions: 343 bool operator<( 344 iterator i_other ) const 345 { return itImpl < i_other.itImpl; } 346 347 // Random Access Iterator functions: 348 iterator & operator+=( 349 difference_type i_diff ) 350 { itImpl += i_diff; return *this; } 351 iterator operator+( 352 difference_type i_diff ) const 353 { iterator ret(itImpl); 354 return ret += i_diff; } 355 iterator & operator-=( 356 difference_type i_diff ) 357 { itImpl -= i_diff; return *this; } 358 iterator operator-( 359 difference_type i_diff ) const 360 { iterator ret(itImpl); 361 return ret -= i_diff; } 362 difference_type operator-( 363 iterator i_it ) const 364 { return itImpl - i_it.itImpl; } 365 XX & operator[]( 366 difference_type i_index ) 367 { return *(*itImpl[i_index]); } 368 369 ////////////////////////////////////////////////////////////////////////// 370 371 private: 372 friend class VirtualVector<XX,PTRDEL>; 373 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 385 VirtualVector<XX,PTRDEL>::VirtualVector() 386 : aData() 387 { 388 } 389 390 template <class XX, class PTRDEL> 391 inline 392 VirtualVector<XX,PTRDEL>::VirtualVector(int i_size) 393 : aData(i_size, 0) 394 { 395 } 396 397 template <class XX, class PTRDEL> 398 inline 399 VirtualVector<XX,PTRDEL>::~VirtualVector() 400 { 401 PTRDEL::Destruct(aData); 402 } 403 404 template <class XX, class PTRDEL> 405 inline const XX & 406 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 & 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 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 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 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 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 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 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 465 VirtualVector<XX,PTRDEL>::empty() const 466 { 467 return aData.empty(); 468 } 469 470 template <class XX, class PTRDEL> 471 inline size_t 472 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 479 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 486 VirtualVector<XX,PTRDEL>::end() const 487 { 488 return const_iterator(aData.end()); 489 } 490 491 template <class XX, class PTRDEL> 492 inline const XX & 493 VirtualVector<XX,PTRDEL>::front() const 494 { 495 return *aData.front(); 496 } 497 498 template <class XX, class PTRDEL> 499 inline const XX & 500 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 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 514 VirtualVector<XX,PTRDEL>::end() 515 { 516 return iterator(aData.end()); 517 } 518 519 template <class XX, class PTRDEL> 520 inline XX & 521 VirtualVector<XX,PTRDEL>::front() 522 { 523 return *aData.front(); 524 } 525 526 template <class XX, class PTRDEL> 527 inline XX & 528 VirtualVector<XX,PTRDEL>::back() 529 { 530 return *aData.back(); 531 } 532 533 534 535 536 } // namespace csv 537 #endif 538