Advertisement
Iwanicki

vector v3

May 14th, 2013
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.26 KB | None | 0 0
  1. #ifndef MYTEMPLATE_VECTOR
  2. #define MYTEMPLATE_VECTOR
  3.  
  4. #include <stdexcept>
  5. #include <algorithm>
  6. #include <cstdlib>
  7. #include "vector_iterator.h"
  8.  
  9. namespace mytemplate
  10. {
  11.     template <class T>
  12.     class vector
  13.     {
  14.     private:
  15.         T* array;
  16.         size_t  m_size;
  17.         size_t  m_capacity;
  18.  
  19.         // oblicza następną potęgę 2 nie mniejszą niż 'number'(może być równa)
  20.         size_t nextGreatestPower( size_t number )
  21.         {
  22.             size_t next_power = number-1;
  23.             next_power |= next_power >> 1;
  24.             next_power |= next_power >> 2;
  25.             next_power |= next_power >> 4;
  26.             next_power |= next_power >> 8;
  27.             next_power |= next_power >> 16;
  28.             ++next_power;
  29.  
  30.             return next_power;
  31.         }
  32.  
  33.         void copyArray( T* dst, const T* src, size_t n )
  34.         {
  35.             for( size_t i = 0; i < n; ++i )
  36.                 dst[i] = src[i];
  37.         }
  38.  
  39.     public:
  40.         vector() : array(nullptr), m_size(0), m_capacity(0) {}
  41.         vector( const vector<T>& vec )
  42.         {
  43.             array = nullptr;
  44.             *this = vec;
  45.         }
  46.         vector( size_t n, const T& val = T() )
  47.         {
  48.             if( n == 0 )
  49.             {
  50.                 m_capacity = 0;
  51.                 m_size = 0;
  52.                 array = nullptr;
  53.                 return;
  54.             }
  55.             m_capacity = nextGreatestPower( n );
  56.             m_size = n;
  57.             array = static_cast<T*>( malloc( m_capacity * sizeof( T ) ) );
  58.             for( size_t i = 0; i < m_capacity; ++i )
  59.                 new (&array[i]) T(val);
  60.         }
  61.         ~vector()
  62.         {
  63.             for( size_t i = 0; i < m_capacity; ++i )
  64.                 array[i].~T();
  65.             free(array);
  66.         }
  67.  
  68.         typedef vector_iterator<T, vector> iterator;
  69.         typedef vector_const_iterator<T, vector> const_iterator;
  70.  
  71.         void push_back( const T& value )
  72.         {
  73.             if( m_capacity == 0 || m_size >= m_capacity )
  74.                 reserve( m_capacity + 2 );
  75.             array[m_size] = value;
  76.             ++m_size;
  77.         }
  78.  
  79.         void pop_back()
  80.         {
  81.             --m_size;
  82.             array[m_size].~T();
  83.             new (&array[m_size]) T();
  84.         }
  85.  
  86.         void insert( size_t position, const T& value )
  87.         {
  88.             if( (m_size == 0 && position == 0) || position == m_size )
  89.             {
  90.                 push_back( value );
  91.                 return;
  92.             }
  93.             else if( position > m_size )
  94.                 throw std::out_of_range( "Vector Subscript Out of Range" );
  95.  
  96.             for( size_t i = m_size; ; --i )
  97.             {
  98.                 if( i == position )
  99.                 {
  100.                     array[i] = value;
  101.                     break;
  102.                 }
  103.                 else
  104.                     array[i] = array[i-1];
  105.             }
  106.             ++m_size;
  107.         }
  108.  
  109.         void insert( const_iterator position, size_t n, const T& val)
  110.         {
  111.             ptrdiff_t pos = position - begin();
  112.             if( static_cast<size_t>(pos) > m_size )
  113.                 throw std::out_of_range( "Vector Subscript Out of Range" );
  114.             if( pos + n > m_capacity )
  115.                 reserve( pos + n );
  116.  
  117.             for( ptrdiff_t i = m_size - 1; i >= pos; --i )
  118.                 array[i + n] = array[i];
  119.  
  120.             m_size += n;
  121.  
  122.             while( n-- )
  123.                 array[pos++] = val;
  124.         }
  125.  
  126.         void erase( size_t position )
  127.         {
  128.             if( position >= m_size )
  129.                 throw std::out_of_range( "Vector Subscript Out of Range" );
  130.  
  131.             array[position].~T();
  132.             new (&array[position]) T();
  133.             for( size_t i = position; i < m_size - 1; ++i )
  134.                 array[i] = array[i+1];
  135.  
  136.             --m_size;
  137.         }
  138.  
  139.         void clear()
  140.         {
  141.             for( size_t i = 0; i < m_size; ++i )
  142.             {
  143.                 array[i].~T();
  144.                 new (&array[i]) T();
  145.             }
  146.  
  147.             m_size = 0;
  148.         }
  149.  
  150.         void reserve( size_t n )
  151.         {
  152.             if( n <= m_capacity )
  153.                 return;
  154.             m_capacity = nextGreatestPower( n );
  155.             T* tmp = array;
  156.             array = static_cast<T*>( malloc( m_capacity * sizeof(T) ) );
  157.             if( array == nullptr )
  158.                 throw std::bad_alloc();
  159.             for( size_t i = 0; i < m_capacity; ++i )
  160.                 new (&array[i]) T();
  161.             copyArray( array, tmp, m_size );
  162.             free(tmp);
  163.         }
  164.  
  165.         void swap( vector<T>& vec )
  166.         {
  167.             std::swap( array, vec.array );
  168.             std::swap( m_size, vec.m_size );
  169.             std::swap( m_capacity, vec.m_capacity );
  170.         }
  171.  
  172.         size_t size() const
  173.         {
  174.             return m_size;
  175.         }
  176.  
  177.         size_t capacity() const
  178.         {
  179.             return m_capacity;
  180.         }
  181.  
  182.         bool empty() const
  183.         {
  184.             if( m_size == 0 )
  185.                 return true;
  186.             else
  187.                 return false;
  188.         }
  189.  
  190.         T& front()
  191.         {
  192.             return array[0];
  193.         }
  194.  
  195.         const T& front() const
  196.         {
  197.             return array[0];
  198.         }
  199.  
  200.         T& back()
  201.         {
  202.             return array[m_size-1];
  203.         }
  204.  
  205.         const T& back() const
  206.         {
  207.             return array[m_size-1];
  208.         }
  209.  
  210.         iterator begin()
  211.         {
  212.             return iterator( &array[0] );
  213.         }
  214.  
  215.         const_iterator begin() const
  216.         {
  217.             return const_iterator( &array[0] );
  218.         }
  219.  
  220.         iterator end()
  221.         {
  222.             return iterator( &array[m_size] );
  223.         }
  224.  
  225.         const_iterator end() const
  226.         {
  227.             return const_iterator( &array[m_size] );
  228.         }
  229.  
  230.         T* data()
  231.         {
  232.             return array;
  233.         }
  234.  
  235.         const T* data() const
  236.         {
  237.             return array;
  238.         }
  239.  
  240.         T& operator[]( size_t index )
  241.         {
  242.             if( index >= m_size )
  243.                 throw std::out_of_range( "Vector Subscript Out of Range" );
  244.             return array[index];
  245.         }
  246.         const T& operator[]( size_t index ) const
  247.         {
  248.             if( index >= m_size )
  249.                 throw std::out_of_range( "Vector Subscript Out of Range" );
  250.             return array[index];
  251.         }
  252.  
  253.         vector<T>& operator=( const vector<T> &vec )
  254.         {
  255.             if( this == &vec )
  256.                 return *this;
  257.             m_size = vec.size();
  258.             m_capacity = vec.capacity();
  259.             T* tmp = array;
  260.             if( vec.capacity() != 0 )
  261.             {
  262.                 array = static_cast<T*>( malloc( m_capacity * sizeof(T) ) );
  263.                 for( size_t i = 0; i < m_capacity; ++i )
  264.                     new (&array[i]) T();
  265.                 copyArray( array, vec.array, m_size );
  266.             }
  267.             else
  268.                 array = nullptr;
  269.             free(tmp);
  270.             return *this; // umożliwia łańcuchowe przypisywanie np: vec1 = vec2 = vec3 = vec4;
  271.         }
  272.     };
  273. }
  274.  
  275. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement