All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PtrVector.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_UTIL_PTRVECTOR_H_
23 #define _BLAZE_UTIL_PTRVECTOR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <algorithm>
31 #include <stdexcept>
32 #include <blaze/util/Algorithm.h>
33 #include <blaze/util/Assert.h>
36 #include <blaze/util/Null.h>
39 #include <blaze/util/PtrIterator.h>
40 #include <blaze/util/Template.h>
41 #include <blaze/util/Types.h>
42 
43 
44 namespace blaze {
45 
46 //=================================================================================================
47 //
48 // CLASS DEFINITION
49 //
50 //=================================================================================================
51 
52 //*************************************************************************************************
266 template< typename T // Type
267  , typename D = PtrDelete // Deletion policy
268  , typename G = OptimalGrowth > // Growth policy
270 {
271  private:
272  //**Friend declarations*************************************************************************
274  template< typename T2, typename D2, typename G2 > friend class PtrVector;
276  //**********************************************************************************************
277 
278  public:
279  //**Type definitions****************************************************************************
280  // Blaze naming convention
281  typedef T* ValueType;
282  typedef T* PointerType;
283  typedef const T* ConstPointerType;
284  typedef T*& ReferenceType;
285  typedef T*const& ConstReferenceType;
286  typedef size_t SizeType;
289  typedef D DeletionPolicy;
290  typedef G GrowthPolicy;
291 
292  // STL iterator requirements
298  typedef SizeType size_type;
299  //**********************************************************************************************
300 
301  //**Forward declarations for nested classes*****************************************************
302  template< typename C > class CastIterator;
303  template< typename C > class ConstCastIterator;
304  //**********************************************************************************************
305 
306  //**Constructors********************************************************************************
309  explicit inline PtrVector( SizeType initCapacity = 0 );
310  inline PtrVector( const PtrVector& pv );
311 
312  template< typename T2, typename D2, typename G2 >
313  inline PtrVector( const PtrVector<T2,D2,G2>& pv );
315  //**********************************************************************************************
316 
317  //**Destructor**********************************************************************************
320  inline ~PtrVector();
322  //**********************************************************************************************
323 
324  //**Assignment operators************************************************************************
327  PtrVector& operator=( const PtrVector& pv );
328 
329  template< typename T2, typename D2, typename G2 >
332  //**********************************************************************************************
333 
334  //**Get functions*******************************************************************************
337  inline SizeType maxSize() const;
338  inline SizeType size() const;
339  template< typename C > inline SizeType size() const;
340  inline SizeType capacity() const;
341  inline bool isEmpty() const;
343  //**********************************************************************************************
344 
345  //**Access functions****************************************************************************
348  inline ReferenceType operator[]( SizeType index );
349  inline ConstReferenceType operator[]( SizeType index ) const;
350  inline ReferenceType front();
351  inline ConstReferenceType front() const;
352  inline ReferenceType back();
353  inline ConstReferenceType back() const;
355  //**********************************************************************************************
356 
357  //**Iterator functions**************************************************************************
360  inline Iterator begin();
361  inline ConstIterator begin() const;
362  template< typename C > inline CastIterator<C> begin();
363  template< typename C > inline ConstCastIterator<C> begin() const;
364 
365  inline Iterator end();
366  inline ConstIterator end() const;
367  template< typename C > inline CastIterator<C> end();
368  template< typename C > inline ConstCastIterator<C> end() const;
370  //**********************************************************************************************
371 
372  //**Element functions***************************************************************************
375  inline void pushBack ( PointerType p );
376  inline void popBack ();
377  inline void releaseBack();
378 
379  template< typename IteratorType >
380  inline void assign( IteratorType first, IteratorType last );
381 
382  inline Iterator insert( Iterator pos, PointerType p );
383 
384  template< typename IteratorType >
385  inline void insert( Iterator pos, IteratorType first, IteratorType last );
386 
388  template< typename IteratorType >
389  inline void insert( Iterator pos, IteratorType* first, IteratorType* last );
392  inline Iterator erase ( Iterator pos );
393  template< typename C > inline CastIterator<C> erase ( CastIterator<C> pos );
394  inline Iterator release( Iterator pos );
395  template< typename C > inline CastIterator<C> release( CastIterator<C> pos );
396  inline void clear ();
398  //**********************************************************************************************
399 
400  //**Utility functions***************************************************************************
403  void reserve( SizeType newCapacity );
404  inline void swap( PtrVector& pv ) /* throw() */;
406  //**********************************************************************************************
407 
408  private:
409  //**Helper functions****************************************************************************
412  inline size_t calcCapacity ( size_t minCapacity ) const;
413  inline void deleteElement( PointerType ptr ) const;
415  //**********************************************************************************************
416 
417  //**Insertion helper functions******************************************************************
420  void insert( T**const pos, PointerType p );
421 
423  template< typename IteratorType >
424  inline void insert( Iterator pos, IteratorType first, IteratorType last, std::input_iterator_tag );
425 
426  template< typename IteratorType >
427  inline void insert( Iterator pos, IteratorType first, IteratorType last, std::random_access_iterator_tag );
430  template< typename IteratorType >
431  void insert( T** pos, IteratorType first, IteratorType last, SizeType n );
433  //**********************************************************************************************
434 
435  //**Member variables****************************************************************************
442 
443  //**********************************************************************************************
444 
445  public:
446  //**CastIterator/ConstCastIterator comparison operators*****************************************
447  // The following comparison operators cannot be defined as namespace or member functions
448  // but have to be injected into the surrounding scope via the Barton-Nackman trick since
449  // the template arguments of nested templates cannot be deduced (C++ standard 14.8.2.4/4).
452 
453  //**********************************************************************************************
460  template< typename L, typename R >
461  friend inline bool operator==( const CastIterator<L>& lhs, const CastIterator<R>& rhs )
462  {
463  return lhs.base() == rhs.base();
464  }
465  //**********************************************************************************************
466 
467  //**********************************************************************************************
474  template< typename L, typename R >
475  friend inline bool operator==( const CastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
476  {
477  return lhs.base() == rhs.base();
478  }
479  //**********************************************************************************************
480 
481  //**********************************************************************************************
488  template< typename L, typename R >
489  friend inline bool operator==( const ConstCastIterator<L>& lhs, const CastIterator<R>& rhs )
490  {
491  return lhs.base() == rhs.base();
492  }
493  //**********************************************************************************************
494 
495  //**********************************************************************************************
502  template< typename L, typename R >
503  friend inline bool operator==( const ConstCastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
504  {
505  return lhs.base() == rhs.base();
506  }
507  //**********************************************************************************************
508 
509  //**********************************************************************************************
516  template< typename L, typename R >
517  friend inline bool operator!=( const CastIterator<L>& lhs, const CastIterator<R>& rhs )
518  {
519  return lhs.base() != rhs.base();
520  }
521  //**********************************************************************************************
522 
523  //**********************************************************************************************
530  template< typename L, typename R >
531  friend inline bool operator!=( const CastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
532  {
533  return lhs.base() != rhs.base();
534  }
535  //**********************************************************************************************
536 
537  //**********************************************************************************************
544  template< typename L, typename R >
545  friend inline bool operator!=( const ConstCastIterator<L>& lhs, const CastIterator<R>& rhs )
546  {
547  return lhs.base() != rhs.base();
548  }
549  //**********************************************************************************************
550 
551  //**********************************************************************************************
558  template< typename L, typename R >
559  friend inline bool operator!=( const ConstCastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
560  {
561  return lhs.base() != rhs.base();
562  }
563  //**********************************************************************************************
564 
566  //**********************************************************************************************
567 };
568 //*************************************************************************************************
569 
570 
571 
572 
573 //=================================================================================================
574 //
575 // CONSTRUCTORS
576 //
577 //=================================================================================================
578 
579 //*************************************************************************************************
586 template< typename T // Type
587  , typename D // Deletion policy
588  , typename G > // Growth policy
589 inline PtrVector<T,D,G>::PtrVector( SizeType initCapacity )
590  : size_( 0 ) // Current size of the pointer vector
591  , capacity_( initCapacity ) // Capacity of the pointer vector
592  , begin_( new PointerType[initCapacity] ) // Pointer to the first element
593  , end_( begin_ ) // Pointer to the last element
594 {}
595 //*************************************************************************************************
596 
597 
598 //*************************************************************************************************
603 template< typename T // Type
604  , typename D // Deletion policy
605  , typename G > // Growth policy
607  : size_( pv.size_ ) // Current size of the pointer vector
608  , capacity_( pv.size_ ) // Capacity of the pointer vector
609  , begin_( new PointerType[capacity_] ) // Pointer to the first element
610  , end_( begin_+size_ ) // Pointer to the last element
611 {
612  for( SizeType i=0; i<size_; ++i )
613  begin_[i] = pv.begin_[i];
614 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
623 template< typename T // Type of the pointer vector
624  , typename D // Deletion policy of the pointer vector
625  , typename G > // Growth policy of the pointer vector
626 template< typename T2 // Type of the foreign pointer vector
627  , typename D2 // Deletion policy of the foreign pointer vector
628  , typename G2 > // Growth policy of the foreign pointer vector
630  : size_( pv.size_ ) // Current size of the pointer vector
631  , capacity_( pv.size_ ) // Capacity of the pointer vector
632  , begin_( new PointerType[capacity_] ) // Pointer to the first element
633  , end_( begin_+size_ ) // Pointer to the last element
634 {
635  for( SizeType i=0; i<size_; ++i )
636  begin_[i] = pv.begin_[i];
637 }
638 //*************************************************************************************************
639 
640 
641 
642 
643 //=================================================================================================
644 //
645 // DESTRUCTOR
646 //
647 //=================================================================================================
648 
649 //*************************************************************************************************
655 template< typename T // Type
656  , typename D // Deletion policy
657  , typename G > // Growth policy
659 {
660  for( PointerType* it=begin_; it!=end_; ++it )
661  deleteElement( *it );
662  delete [] begin_;
663 }
664 //*************************************************************************************************
665 
666 
667 
668 
669 //=================================================================================================
670 //
671 // ASSIGNMENT OPERATORS
672 //
673 //=================================================================================================
674 
675 //*************************************************************************************************
681 template< typename T // Type
682  , typename D // Deletion policy
683  , typename G > // Growth policy
685 {
686  if( &pv == this ) return *this;
687 
688  if( pv.size_ > capacity_ ) {
689  PointerType* newBegin( new PointerType[pv.size_] );
690  end_ = std::copy( pv.begin_, pv.end_, newBegin );
691  std::swap( begin_, newBegin );
692  delete [] newBegin;
693 
694  size_ = pv.size_;
695  capacity_ = pv.size_;
696  }
697  else {
698  end_ = std::copy( pv.begin_, pv.end_, begin_ );
699  size_ = pv.size_;
700  }
701 
702  return *this;
703 }
704 //*************************************************************************************************
705 
706 
707 //*************************************************************************************************
713 template< typename T // Type of the pointer vector
714  , typename D // Deletion policy of the pointer vector
715  , typename G > // Growth policy of the pointer vector
716 template< typename T2 // Type of the foreign pointer vector
717  , typename D2 // Deletion policy of the foreign pointer vector
718  , typename G2 > // Growth policy of the foreign pointer vector
720 {
721  if( pv.size_ > capacity_ ) {
722  PointerType* newBegin( new PointerType[pv.size_] );
723  end_ = std::copy( pv.begin_, pv.end_, newBegin );
724  std::swap( begin_, newBegin );
725  delete [] newBegin;
726 
727  size_ = pv.size_;
728  capacity_ = pv.size_;
729  }
730  else {
731  end_ = std::copy( pv.begin_, pv.end_, begin_ );
732  size_ = pv.size_;
733  }
734 
735  return *this;
736 }
737 //*************************************************************************************************
738 
739 
740 
741 
742 //=================================================================================================
743 //
744 // GET FUNCTIONS
745 //
746 //=================================================================================================
747 
748 //*************************************************************************************************
753 template< typename T // Type
754  , typename D // Deletion policy
755  , typename G > // Growth policy
757 {
758  return SizeType(-1) / sizeof(PointerType);
759 }
760 //*************************************************************************************************
761 
762 
763 //*************************************************************************************************
768 template< typename T // Type
769  , typename D // Deletion policy
770  , typename G > // Growth policy
772 {
773  return size_;
774 }
775 //*************************************************************************************************
776 
777 
778 //*************************************************************************************************
806 template< typename T // Type
807  , typename D // Deletion policy
808  , typename G > // Growth policy
809 template< typename C > // Cast type
811 {
812  // The polymorphicCount() function returns the number of objects with dynamic type 'C'
813  // contained in the range [begin,end). An equivalent code might look like this:
814  //
815  // SizeType count( 0 );
816  // for( PointerType* it=begin_; it!=end_; ++it )
817  // if( dynamic_cast<C*>( *it ) ) ++count;
818  // return count;
819  //
820  // However, the specialization of polymorphicCount() for special type combinations is
821  // much more efficient (and easier) than the specialization of this function!
822  return polymorphicCount<C>( begin_, end_ );
823 }
824 //*************************************************************************************************
825 
826 
827 //*************************************************************************************************
832 template< typename T // Type
833  , typename D // Deletion policy
834  , typename G > // Growth policy
836 {
837  return capacity_;
838 }
839 //*************************************************************************************************
840 
841 
842 //*************************************************************************************************
847 template< typename T // Type
848  , typename D // Deletion policy
849  , typename G > // Growth policy
850 inline bool PtrVector<T,D,G>::isEmpty() const
851 {
852  return size_ == 0;
853 }
854 //*************************************************************************************************
855 
856 
857 
858 
859 //=================================================================================================
860 //
861 // ACCESS FUNCTIONS
862 //
863 //=================================================================================================
864 
865 //*************************************************************************************************
873 template< typename T // Type
874  , typename D // Deletion policy
875  , typename G > // Growth policy
877 {
878  return *(begin_+index);
879 }
880 //*************************************************************************************************
881 
882 
883 //*************************************************************************************************
891 template< typename T // Type
892  , typename D // Deletion policy
893  , typename G > // Growth policy
895 {
896  return *(begin_+index);
897 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
908 template< typename T // Type
909  , typename D // Deletion policy
910  , typename G > // Growth policy
912 {
913  BLAZE_USER_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the front element" );
914  return *begin_;
915 }
916 //*************************************************************************************************
917 
918 
919 //*************************************************************************************************
926 template< typename T // Type
927  , typename D // Deletion policy
928  , typename G > // Growth policy
930 {
931  BLAZE_USER_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the front element" );
932  return *begin_;
933 }
934 //*************************************************************************************************
935 
936 
937 //*************************************************************************************************
944 template< typename T // Type
945  , typename D // Deletion policy
946  , typename G > // Growth policy
948 {
949  BLAZE_USER_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the back element" );
950  return *(end_-1);
951 }
952 //*************************************************************************************************
953 
954 
955 //*************************************************************************************************
962 template< typename T // Type
963  , typename D // Deletion policy
964  , typename G > // Growth policy
966 {
967  BLAZE_USER_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the back element" );
968  return *(end_-1);
969 }
970 //*************************************************************************************************
971 
972 
973 
974 
975 //=================================================================================================
976 //
977 // ITERATOR FUNCTIONS
978 //
979 //=================================================================================================
980 
981 //*************************************************************************************************
986 template< typename T // Type
987  , typename D // Deletion policy
988  , typename G > // Growth policy
990 {
991  return Iterator( begin_ );
992 }
993 //*************************************************************************************************
994 
995 
996 //*************************************************************************************************
1001 template< typename T // Type
1002  , typename D // Deletion policy
1003  , typename G > // Growth policy
1005 {
1006  return ConstIterator( begin_ );
1007 }
1008 //*************************************************************************************************
1009 
1010 
1011 //*************************************************************************************************
1056 template< typename T // Type
1057  , typename D // Deletion policy
1058  , typename G > // Growth policy
1059 template< typename C > // Cast type
1060 inline typename PtrVector<T,D,G>::BLAZE_TEMPLATE CastIterator<C> PtrVector<T,D,G>::begin()
1061 {
1062  return CastIterator<C>( begin_, end_ );
1063 }
1064 //*************************************************************************************************
1065 
1066 
1067 //*************************************************************************************************
1112 template< typename T // Type
1113  , typename D // Deletion policy
1114  , typename G > // Growth policy
1115 template< typename C > // Cast type
1116 inline typename PtrVector<T,D,G>::BLAZE_TEMPLATE ConstCastIterator<C> PtrVector<T,D,G>::begin() const
1117 {
1118  return ConstCastIterator<C>( begin_, end_ );
1119 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1128 template< typename T // Type
1129  , typename D // Deletion policy
1130  , typename G > // Growth policy
1132 {
1133  return Iterator( end_ );
1134 }
1135 //*************************************************************************************************
1136 
1137 
1138 //*************************************************************************************************
1143 template< typename T // Type
1144  , typename D // Deletion policy
1145  , typename G > // Growth policy
1147 {
1148  return ConstIterator( end_ );
1149 }
1150 //*************************************************************************************************
1151 
1152 
1153 //*************************************************************************************************
1195 template< typename T // Type
1196  , typename D // Deletion policy
1197  , typename G > // Growth policy
1198 template< typename C > // Cast type
1199 inline typename PtrVector<T,D,G>::BLAZE_TEMPLATE CastIterator<C> PtrVector<T,D,G>::end()
1200 {
1201  return CastIterator<C>( end_, end_ );
1202 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1248 template< typename T // Type
1249  , typename D // Deletion policy
1250  , typename G > // Growth policy
1251 template< typename C > // Cast type
1252 inline typename PtrVector<T,D,G>::BLAZE_TEMPLATE ConstCastIterator<C> PtrVector<T,D,G>::end() const
1253 {
1254  return ConstCastIterator<C>( end_, end_ );
1255 }
1256 //*************************************************************************************************
1257 
1258 
1259 
1260 
1261 //=================================================================================================
1262 //
1263 // ELEMENT FUNCTIONS
1264 //
1265 //=================================================================================================
1266 
1267 //*************************************************************************************************
1276 template< typename T // Type
1277  , typename D // Deletion policy
1278  , typename G > // Growth policy
1280 {
1281  if( size_ != capacity_ ) {
1282  *end_ = p;
1283  ++end_;
1284  ++size_;
1285  }
1286  else {
1287  insert( end_, p );
1288  }
1289 }
1290 //*************************************************************************************************
1291 
1292 
1293 //*************************************************************************************************
1303 template< typename T // Type
1304  , typename D // Deletion policy
1305  , typename G > // Growth policy
1307 {
1308  deleteElement( *--end_ );
1309  --size_;
1310 }
1311 //*************************************************************************************************
1312 
1313 
1314 //*************************************************************************************************
1324 template< typename T // Type
1325  , typename D // Deletion policy
1326  , typename G > // Growth policy
1328 {
1329  --end_;
1330  --size_;
1331 }
1332 //*************************************************************************************************
1333 
1334 
1335 //*************************************************************************************************
1347 template< typename T // Type
1348  , typename D // Deletion policy
1349  , typename G > // Growth policy
1350 template< typename IteratorType >
1351 inline void PtrVector<T,D,G>::assign( IteratorType first, IteratorType last )
1352 {
1353  clear();
1354  insert( end(), first, last );
1355 }
1356 //*************************************************************************************************
1357 
1358 
1359 //*************************************************************************************************
1370 template< typename T // Type
1371  , typename D // Deletion policy
1372  , typename G > // Growth policy
1374 {
1375  T** const base = const_cast<T**>( pos.base() );
1376  const SizeType diff( base - begin_ );
1377 
1378  if( size_ != capacity_ && base == end_ ) {
1379  *end_ = p;
1380  ++end_;
1381  ++size_;
1382  }
1383  else {
1384  insert( base, p );
1385  }
1386 
1387  return Iterator( begin_+diff );
1388 }
1389 //*************************************************************************************************
1390 
1391 
1392 //*************************************************************************************************
1405 template< typename T // Type
1406  , typename D // Deletion policy
1407  , typename G > // Growth policy
1408 template< typename IteratorType >
1409 inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last )
1410 {
1411  insert( pos, first, last, typename IteratorType::iterator_category() );
1412 }
1413 //*************************************************************************************************
1414 
1415 
1416 //*************************************************************************************************
1430 template< typename T // Type
1431  , typename D // Deletion policy
1432  , typename G > // Growth policy
1433 template< typename IteratorType >
1434 inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType* first, IteratorType* last )
1435 {
1436  insert( pos, first, last, std::random_access_iterator_tag() );
1437 }
1439 //*************************************************************************************************
1440 
1441 
1442 //*************************************************************************************************
1453 template< typename T // Type
1454  , typename D // Deletion policy
1455  , typename G > // Growth policy
1457 {
1458  T** const base = const_cast<T**>( pos.base() );
1459  deleteElement( *base );
1460  std::copy( base+1, end_, base );
1461 
1462  --size_;
1463  --end_;
1464 
1465  return pos;
1466 }
1467 //*************************************************************************************************
1468 
1469 
1470 //*************************************************************************************************
1481 template< typename T // Type
1482  , typename D // Deletion policy
1483  , typename G > // Growth policy
1484 template< typename C > // Cast type
1485 inline typename PtrVector<T,D,G>::BLAZE_TEMPLATE CastIterator<C>
1487 {
1488  T** const base = const_cast<T**>( pos.base() );
1489  deleteElement( *base );
1490  std::copy( base+1, end_, base );
1491 
1492  --size_;
1493  --end_;
1494 
1495  return CastIterator<C>( base, end_ );
1496 }
1497 //*************************************************************************************************
1498 
1499 
1500 //*************************************************************************************************
1510 template< typename T // Type
1511  , typename D // Deletion policy
1512  , typename G > // Growth policy
1514 {
1515  T** const base = const_cast<T**>( pos.base() );
1516  std::copy( base+1, end_, base );
1517 
1518  --size_;
1519  --end_;
1520 
1521  return pos;
1522 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1536 template< typename T // Type
1537  , typename D // Deletion policy
1538  , typename G > // Growth policy
1539 template< typename C > // Cast type
1540 inline typename PtrVector<T,D,G>::BLAZE_TEMPLATE CastIterator<C>
1542 {
1543  T** const base = const_cast<T**>( pos.base() );
1544  std::copy( base+1, end_, base );
1545 
1546  --size_;
1547  --end_;
1548 
1549  return CastIterator<C>( base, end_ );
1550 }
1551 //*************************************************************************************************
1552 
1553 
1554 //*************************************************************************************************
1559 template< typename T // Type
1560  , typename D // Deletion policy
1561  , typename G > // Growth policy
1563 {
1564  for( PointerType* it=begin_; it!=end_; ++it )
1565  deleteElement( *it );
1566 
1567  end_ = begin_;
1568  size_ = 0;
1569 }
1570 //*************************************************************************************************
1571 
1572 
1573 
1574 
1575 //=================================================================================================
1576 //
1577 // UTILITY FUNCTIONS
1578 //
1579 //=================================================================================================
1580 
1581 //*************************************************************************************************
1587 template< typename T // Type
1588  , typename D // Deletion policy
1589  , typename G > // Growth policy
1591 {
1592  if( newCapacity > capacity_ )
1593  {
1594  // Calculating the new capacity
1595  newCapacity = calcCapacity( newCapacity );
1596 
1597  // Allocating a new array
1598  PointerType* tmp = new PointerType[newCapacity];
1599 
1600  // Replacing the old array
1601  std::copy( begin_, end_, tmp );
1602  std::swap( tmp, begin_ );
1603  capacity_ = newCapacity;
1604  end_ = begin_ + size_;
1605  delete [] tmp;
1606  }
1607 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1618 template< typename T // Type
1619  , typename D // Deletion policy
1620  , typename G > // Growth policy
1621 inline void PtrVector<T,D,G>::swap( PtrVector& pv ) /* throw() */
1622 {
1623  // By using the 'std::swap' function to swap all member variables,
1624  // the function can give the nothrow guarantee.
1625  std::swap( size_, pv.size_ );
1626  std::swap( capacity_, pv.capacity_ );
1627  std::swap( begin_, pv.begin_ );
1628  std::swap( end_, pv.end_ );
1629 }
1630 //*************************************************************************************************
1631 
1632 
1633 
1634 
1635 //=================================================================================================
1636 //
1637 // HELPER FUNCTIONS
1638 //
1639 //=================================================================================================
1640 
1641 //*************************************************************************************************
1647 template< typename T // Type
1648  , typename D // Deletion policy
1649  , typename G > // Growth policy
1650 inline size_t PtrVector<T,D,G>::calcCapacity( size_t minCapacity ) const
1651 {
1652  BLAZE_INTERNAL_ASSERT( minCapacity > capacity_, "Invalid new vector capacity" );
1653  const size_t newCapacity( GrowthPolicy()( capacity_, minCapacity ) );
1654  BLAZE_INTERNAL_ASSERT( newCapacity > capacity_, "Invalid new vector capacity" );
1655  return newCapacity;
1656 }
1657 //*************************************************************************************************
1658 
1659 
1660 //*************************************************************************************************
1666 template< typename T // Type
1667  , typename D // Deletion policy
1668  , typename G > // Growth policy
1670 {
1671  DeletionPolicy()( ptr );
1672 }
1673 //*************************************************************************************************
1674 
1675 
1676 
1677 
1678 //=================================================================================================
1679 //
1680 // INSERTION HELPER FUNCTIONS
1681 //
1682 //=================================================================================================
1683 
1684 //*************************************************************************************************
1692 template< typename T // Type
1693  , typename D // Deletion policy
1694  , typename G > // Growth policy
1695 void PtrVector<T,D,G>::insert( T**const pos, PointerType p )
1696 {
1697  if( size_ != capacity_ ) {
1698  std::copy_backward( pos, end_, end_+1 );
1699  *pos = p;
1700  ++end_;
1701  ++size_;
1702  }
1703  else if( size_ == maxSize() ) {
1704  throw std::length_error( "Maximum pointer vector length exceeded!" );
1705  }
1706  else {
1707  SizeType newCapacity( calcCapacity( capacity_+1 ) );
1708  if( newCapacity > maxSize() || newCapacity < capacity_ ) newCapacity = maxSize();
1709 
1710  PointerType* newBegin = new PointerType[newCapacity];
1711  PointerType* newEnd = std::copy( begin_, pos, newBegin );
1712  *newEnd = p;
1713  ++newEnd;
1714  end_ = std::copy( pos, end_, newEnd );
1715 
1716  std::swap( newBegin, begin_ );
1717  delete [] newBegin;
1718  capacity_ = newCapacity;
1719  ++size_;
1720  }
1721 }
1722 //*************************************************************************************************
1723 
1724 
1725 //*************************************************************************************************
1738 template< typename T // Type
1739  , typename D // Deletion policy
1740  , typename G > // Growth policy
1741 template< typename IteratorType >
1742 inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last,
1743  std::input_iterator_tag )
1744 {
1745  for( ; first!=last; ++first ) {
1746  pos = insert( pos, *first );
1747  ++pos;
1748  }
1749 }
1751 //*************************************************************************************************
1752 
1753 
1754 //*************************************************************************************************
1767 template< typename T // Type
1768  , typename D // Deletion policy
1769  , typename G > // Growth policy
1770 template< typename IteratorType >
1771 inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last,
1772  std::random_access_iterator_tag )
1773 {
1774  T** const base = const_cast<T**>( pos.base() );
1775  const SizeType diff( last - first );
1776 
1777  if( size_+diff <= capacity_ && base == end_ ) {
1778  for( ; first!=last; ++first, ++end_ ) {
1779  *end_ = *first;
1780  }
1781  size_ += diff;
1782  }
1783  else {
1784  insert( base, first, last, diff );
1785  }
1786 }
1788 //*************************************************************************************************
1789 
1790 
1791 //*************************************************************************************************
1801 template< typename T // Type
1802  , typename D // Deletion policy
1803  , typename G > // Growth policy
1804 template< typename IteratorType >
1805 void PtrVector<T,D,G>::insert( T** pos, IteratorType first, IteratorType last, SizeType n )
1806 {
1807  const SizeType newSize( size_ + n );
1808 
1809  if( newSize <= capacity_ ) {
1810  std::copy_backward( pos, end_, end_+n );
1811  for( ; first!=last; ++first, ++pos ) {
1812  *pos = *first;
1813  }
1814  end_ += n;
1815  size_ = newSize;
1816  }
1817  else if( newSize > maxSize() || newSize < size_ ) {
1818  throw std::length_error( "Maximum pointer vector length exceeded!" );
1819  }
1820  else {
1821  PointerType* newBegin = new PointerType[newSize];
1822  PointerType* newEnd = std::copy( begin_, pos, newBegin );
1823 
1824  for( ; first!=last; ++first, ++newEnd ) {
1825  *newEnd = *first;
1826  }
1827 
1828  end_ = std::copy( pos, end_, newEnd );
1829 
1830  std::swap( newBegin, begin_ );
1831  delete [] newBegin;
1832  capacity_ = newSize;
1833  size_ = newSize;
1834  }
1835 }
1836 //*************************************************************************************************
1837 
1838 
1839 
1840 
1841 //=================================================================================================
1842 //
1843 // GLOBAL OPERATORS
1844 //
1845 //=================================================================================================
1846 
1847 //*************************************************************************************************
1850 template< typename T, typename D, typename G >
1851 inline bool operator==( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs );
1852 
1853 template< typename T, typename D, typename G >
1854 inline bool operator!=( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs );
1855 
1856 template< typename T, typename D, typename G >
1857 inline void swap( PtrVector<T,D,G>& a, PtrVector<T,D,G>& b ) /* throw() */;
1859 //*************************************************************************************************
1860 
1861 
1862 //*************************************************************************************************
1869 template< typename T // Type
1870  , typename D // Deletion policy
1871  , typename G > // Growth policy
1872 inline bool operator==( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs )
1873 {
1874  return lhs.size() == rhs.size() && std::equal( lhs.begin(), lhs.end(), rhs.begin() );
1875 }
1876 //*************************************************************************************************
1877 
1878 
1879 //*************************************************************************************************
1886 template< typename T // Type
1887  , typename D // Deletion policy
1888  , typename G > // Growth policy
1889 inline bool operator!=( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs )
1890 {
1891  return lhs.size() != rhs.size() || !std::equal( lhs.begin(), lhs.end(), rhs.begin() );
1892 }
1893 //*************************************************************************************************
1894 
1895 
1896 //*************************************************************************************************
1904 template< typename T // Type
1905  , typename D // Deletion policy
1906  , typename G > // Growth policy
1907 inline void swap( PtrVector<T,D,G>& a, PtrVector<T,D,G>& b ) /* throw() */
1908 {
1909  a.swap( b );
1910 }
1911 //*************************************************************************************************
1912 
1913 
1914 
1915 
1916 
1917 
1918 
1919 
1920 //=================================================================================================
1921 //
1922 // NESTED CLASS PTRVECTOR::CASTITERATOR
1923 //
1924 //=================================================================================================
1925 
1926 //*************************************************************************************************
1949 template< typename T // Type
1950  , typename D // Deletion policy
1951  , typename G > // Growth policy
1952 template< typename C > // Cast type
1953 class PtrVector<T,D,G>::CastIterator
1954 {
1955  public:
1956  //**Type definitions****************************************************************************
1957  // Blaze naming convention
1958  typedef std::forward_iterator_tag IteratorCategory;
1959  typedef C* ValueType;
1960  typedef C* PointerType;
1961  typedef C* const& ReferenceType;
1963  typedef T* const* IteratorType;
1964 
1965  // STL iterator requirements
1971  //**********************************************************************************************
1972 
1973  //**Constructors********************************************************************************
1976  inline CastIterator();
1978 
1979  template< typename Other >
1980  inline CastIterator( const CastIterator<Other>& it );
1981 
1982  // No explicitly declared copy constructor.
1984  //**********************************************************************************************
1985 
1986  //**Destructor**********************************************************************************
1987  // No explicitly declared destructor.
1988  //**********************************************************************************************
1989 
1990  //**Copy assignment operator********************************************************************
1991  // No explicitly declared copy assignment operator.
1992  //**********************************************************************************************
1993 
1994  //**Operators***********************************************************************************
1997  inline CastIterator& operator++();
1998  inline CastIterator operator++( int );
2000  //**********************************************************************************************
2001 
2002  //**Access operators****************************************************************************
2005  inline PointerType operator*() const;
2006  inline PointerType operator->() const;
2008  //**********************************************************************************************
2009 
2010  //**Utility functions***************************************************************************
2013  inline const IteratorType& base() const;
2014  inline const IteratorType& stop() const;
2016  //**********************************************************************************************
2017 
2018  private:
2019  //**Member variables****************************************************************************
2024 
2025  //**********************************************************************************************
2026 };
2027 //*************************************************************************************************
2028 
2029 
2030 
2031 
2032 //=================================================================================================
2033 //
2034 // CONSTRUCTOR
2035 //
2036 //=================================================================================================
2037 
2038 //*************************************************************************************************
2041 template< typename T // Type
2042  , typename D // Deletion policy
2043  , typename G > // Growth policy
2044 template< typename C > // Cast type
2046  : cur_(NULL) // Pointer to the current memory location
2047  , end_(NULL) // Pointer to the element one past the last element in the element range
2048 {
2050 }
2051 //*************************************************************************************************
2052 
2053 
2054 //*************************************************************************************************
2060 template< typename T // Type
2061  , typename D // Deletion policy
2062  , typename G > // Growth policy
2063 template< typename C > // Cast type
2065  : cur_(begin) // Pointer to the current memory location
2066  , end_(end) // Pointer to the element one past the last element in the element range
2067 {
2068  // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
2069  // contained in the range [cur_,end). An equivalent code might look like this:
2070  //
2071  // while( cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) ++cur_;
2072  //
2073  // However, the specialization of polymorphicFind() for special type combinations is much
2074  // more efficient (and way easier!) than the specialization of this function!
2075  cur_ = polymorphicFind<C>( cur_, end_ );
2076 }
2077 //*************************************************************************************************
2078 
2079 
2080 //*************************************************************************************************
2085 template< typename T // Type
2086  , typename D // Deletion policy
2087  , typename G > // Growth policy
2088 template< typename C > // Cast type
2089 template< typename Other > // The foreign cast iterator type
2091  : cur_( it.base() ) // Pointer to the current memory location
2092  , end_( it.stop() ) // Pointer to the element one past the last element in the element range
2093 {
2096 }
2097 //*************************************************************************************************
2098 
2099 
2100 
2101 
2102 //=================================================================================================
2103 //
2104 // OPERATORS
2105 //
2106 //=================================================================================================
2107 
2108 //*************************************************************************************************
2113 template< typename T // Type
2114  , typename D // Deletion policy
2115  , typename G > // Growth policy
2116 template< typename C > // Cast type
2119 {
2120  // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
2121  // contained in the range [cur_+1,end). An equivalent code might look like this:
2122  //
2123  // while( ++cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) {}
2124  //
2125  // However, the specialization of polymorphicFind() for special type combinations is much
2126  // more efficient (and way easier!) than the specialization of this function!
2127  cur_ = polymorphicFind<C>( ++cur_, end_ );
2128 
2129  return *this;
2130 }
2131 //*************************************************************************************************
2132 
2133 
2134 //*************************************************************************************************
2139 template< typename T // Type
2140  , typename D // Deletion policy
2141  , typename G > // Growth policy
2142 template< typename C > // Cast type
2145 {
2146  CastIterator tmp( *this );
2147 
2148  // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
2149  // contained in the range [cur_+1,end). An equivalent code might look like this:
2150  //
2151  // while( ++cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) {}
2152  //
2153  // However, the specialization of polymorphicFind() for special type combinations is much
2154  // more efficient (and way easier!) than the specialization of this function!
2155  cur_ = polymorphicFind<C>( ++cur_, end_ );
2156 
2157  return tmp;
2158 }
2159 //*************************************************************************************************
2160 
2161 
2162 
2163 
2164 //=================================================================================================
2165 //
2166 // ACCESS OPERATORS
2167 //
2168 //=================================================================================================
2169 
2170 //*************************************************************************************************
2175 template< typename T // Type
2176  , typename D // Deletion policy
2177  , typename G > // Growth policy
2178 template< typename C > // Cast type
2181 {
2182  return static_cast<C*>( *cur_ );
2183 }
2184 //*************************************************************************************************
2185 
2186 
2187 //*************************************************************************************************
2192 template< typename T // Type
2193  , typename D // Deletion policy
2194  , typename G > // Growth policy
2195 template< typename C > // Cast type
2198 {
2199  return static_cast<C*>( *cur_ );
2200 }
2201 //*************************************************************************************************
2202 
2203 
2204 
2205 
2206 //=================================================================================================
2207 //
2208 // UTILITY FUNCTIONS
2209 //
2210 //=================================================================================================
2211 
2212 //*************************************************************************************************
2217 template< typename T // Type
2218  , typename D // Deletion policy
2219  , typename G > // Growth policy
2220 template< typename C > // Cast type
2223 {
2224  return cur_;
2225 }
2226 //*************************************************************************************************
2227 
2228 
2229 //*************************************************************************************************
2234 template< typename T // Type
2235  , typename D // Deletion policy
2236  , typename G > // Growth policy
2237 template< typename C > // Cast type
2240 {
2241  return end_;
2242 }
2243 //*************************************************************************************************
2244 
2245 
2246 
2247 
2248 
2249 
2250 
2251 
2252 //=================================================================================================
2253 //
2254 // NESTED CLASS PTRVECTOR::CONSTCASTITERATOR
2255 //
2256 //=================================================================================================
2257 
2258 //*************************************************************************************************
2282 template< typename T // Type
2283  , typename D // Deletion policy
2284  , typename G > // Growth policy
2285 template< typename C > // Cast type
2286 class PtrVector<T,D,G>::ConstCastIterator
2287 {
2288  public:
2289  //**Type definitions****************************************************************************
2290  // Blaze naming convention
2291  typedef std::forward_iterator_tag IteratorCategory;
2292  typedef const C* ValueType;
2293  typedef const C* PointerType;
2294  typedef const C* const& ReferenceType;
2296  typedef const T* const* IteratorType;
2297 
2298  // STL iterator requirements
2304  //**********************************************************************************************
2305 
2306  //**Constructors********************************************************************************
2309  inline ConstCastIterator();
2311 
2312  template< typename Other >
2313  inline ConstCastIterator( const ConstCastIterator<Other>& it );
2314 
2315  template< typename Other >
2317 
2318  // No explicitly declared copy constructor.
2320  //**********************************************************************************************
2321 
2322  //**Destructor**********************************************************************************
2323  // No explicitly declared destructor.
2324  //**********************************************************************************************
2325 
2326  //**Copy assignment operator********************************************************************
2327  // No explicitly declared copy assignment operator.
2328  //**********************************************************************************************
2329 
2330  //**Operators***********************************************************************************
2333  inline ConstCastIterator& operator++();
2334  inline ConstCastIterator operator++( int );
2336  //**********************************************************************************************
2337 
2338  //**Access operators****************************************************************************
2341  inline PointerType operator*() const;
2342  inline PointerType operator->() const;
2344  //**********************************************************************************************
2345 
2346  //**Utility functions***************************************************************************
2349  inline const IteratorType& base() const;
2350  inline const IteratorType& stop() const;
2352  //**********************************************************************************************
2353 
2354  private:
2355  //**Member variables****************************************************************************
2360 
2361  //**********************************************************************************************
2362 };
2363 //*************************************************************************************************
2364 
2365 
2366 
2367 
2368 //=================================================================================================
2369 //
2370 // CONSTRUCTOR
2371 //
2372 //=================================================================================================
2373 
2374 //*************************************************************************************************
2377 template< typename T // Type
2378  , typename D // Deletion policy
2379  , typename G > // Growth policy
2380 template< typename C > // Cast type
2382  : cur_(NULL) // Pointer to the current memory location
2383  , end_(NULL) // Pointer to the element one past the last element in the element range
2384 {
2386 }
2387 //*************************************************************************************************
2388 
2389 
2390 //*************************************************************************************************
2396 template< typename T // Type
2397  , typename D // Deletion policy
2398  , typename G > // Growth policy
2399 template< typename C > // Cast type
2401  : cur_(begin) // Pointer to the current memory location
2402  , end_(end) // Pointer to the element one past the last element in the element range
2403 {
2404  // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
2405  // contained in the range [cur_,end). An equivalent code might look like this:
2406  //
2407  // while( cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) ++cur_;
2408  //
2409  // However, the specialization of polymorphicFind() for special type combinations is much
2410  // more efficient (and way easier!) than the specialization of this function!
2411  cur_ = polymorphicFind<C>( cur_, end_ );
2412 }
2413 //*************************************************************************************************
2414 
2415 
2416 //*************************************************************************************************
2421 template< typename T // Type
2422  , typename D // Deletion policy
2423  , typename G > // Growth policy
2424 template< typename C > // Cast type
2425 template< typename Other > // The foreign constant cast iterator type
2427  : cur_( it.base() ) // Pointer to the current memory location
2428  , end_( it.stop() ) // Pointer to the element one past the last element in the element range
2429 {
2432 }
2433 //*************************************************************************************************
2434 
2435 
2436 //*************************************************************************************************
2441 template< typename T // Type
2442  , typename D // Deletion policy
2443  , typename G > // Growth policy
2444 template< typename C > // Cast type
2445 template< typename Other > // The foreign cast iterator type
2447  : cur_( it.base() ) // Pointer to the current memory location
2448  , end_( it.stop() ) // Pointer to the element one past the last element in the element range
2449 {
2452 }
2453 //*************************************************************************************************
2454 
2455 
2456 
2457 
2458 //=================================================================================================
2459 //
2460 // OPERATORS
2461 //
2462 //=================================================================================================
2463 
2464 //*************************************************************************************************
2469 template< typename T // Type
2470  , typename D // Deletion policy
2471  , typename G > // Growth policy
2472 template< typename C > // Cast type
2475 {
2476  // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
2477  // contained in the range [cur_+1,end). An equivalent code might look like this:
2478  //
2479  // while( ++cur_ != end_ && !dynamic_cast<const C*>( *cur_ ) ) {}
2480  //
2481  // However, the specialization of polymorphicFind() for special type combinations is much
2482  // more efficient (and way easier!) than the specialization of this function!
2483  cur_ = polymorphicFind<const C>( ++cur_, end_ );
2484 
2485  return *this;
2486 }
2487 //*************************************************************************************************
2488 
2489 
2490 //*************************************************************************************************
2495 template< typename T // Type
2496  , typename D // Deletion policy
2497  , typename G > // Growth policy
2498 template< typename C > // Cast type
2501 {
2502  ConstCastIterator tmp( *this );
2503 
2504  // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
2505  // contained in the range [cur_+1,end). An equivalent code might look like this:
2506  //
2507  // while( ++cur_ != end_ && !dynamic_cast<const C*>( *cur_ ) ) {}
2508  //
2509  // However, the specialization of polymorphicFind() for special type combinations is much
2510  // more efficient (and way easier!) than the specialization of this function!
2511  cur_ = polymorphicFind<const C>( ++cur_, end_ );
2512 
2513  return tmp;
2514 }
2515 //*************************************************************************************************
2516 
2517 
2518 
2519 
2520 //=================================================================================================
2521 //
2522 // ACCESS OPERATORS
2523 //
2524 //=================================================================================================
2525 
2526 //*************************************************************************************************
2531 template< typename T // Type
2532  , typename D // Deletion policy
2533  , typename G > // Growth policy
2534 template< typename C > // Cast type
2537 {
2538  return static_cast<const C*>( *cur_ );
2539 }
2540 //*************************************************************************************************
2541 
2542 
2543 //*************************************************************************************************
2548 template< typename T // Type
2549  , typename D // Deletion policy
2550  , typename G > // Growth policy
2551 template< typename C > // Cast type
2554 {
2555  return static_cast<const C*>( *cur_ );
2556 }
2557 //*************************************************************************************************
2558 
2559 
2560 
2561 
2562 //=================================================================================================
2563 //
2564 // UTILITY FUNCTIONS
2565 //
2566 //=================================================================================================
2567 
2568 //*************************************************************************************************
2573 template< typename T // Type
2574  , typename D // Deletion policy
2575  , typename G > // Growth policy
2576 template< typename C > // Cast type
2579 {
2580  return cur_;
2581 }
2582 //*************************************************************************************************
2583 
2584 
2585 //*************************************************************************************************
2590 template< typename T // Type
2591  , typename D // Deletion policy
2592  , typename G > // Growth policy
2593 template< typename C > // Cast type
2596 {
2597  return end_;
2598 }
2599 //*************************************************************************************************
2600 
2601 } // namespace blaze
2602 
2603 #endif