Untitled

 avatar
unknown
c_cpp
a year ago
6.0 kB
4
Indexable
#ifndef VECTOR_HPP
#define VECTOR_HPP

#include <iostream>
#include <stdexcept>
#include <initializer_list>

template< typename T >
class Vector
{
public:
    Vector();
    Vector( std::initializer_list< T > init );
    Vector( const Vector& other );
    Vector( Vector&& other ) noexcept;

    explicit Vector( const T& value );
    explicit Vector( size_t size, const T& value );
    Vector( T* first, T* last );

    ~Vector();

    Vector& operator=( const Vector& other );
    Vector& operator=( Vector&& other ) noexcept;

    T& operator[]( size_t index );
    const T& operator[]( size_t index ) const;

    bool operator==( const Vector& other ) const;
    bool operator!=( const Vector& other ) const;

    void push_back( const T& value );
    void push_back( T&& value );
    void pop_back();
    void clear();

    size_t size() const;
    size_t capacity() const;
    bool empty() const;
    void reserve( size_t newCapacity );

    T* begin();
    T* end();
    const T* begin() const;
    const T* end() const;

private:
    void reallocate( size_t newCapacity );

    T* data_;
    size_t size_;
    size_t capacity_;
};

template< typename T >
Vector< T >::Vector() : data_( nullptr ), size_( 0 ), capacity_( 0 )
{
    // Empty body.
}

template< typename T >
Vector< T >::Vector( std::initializer_list< T > init ) : Vector()
{
    for( const T& item : init )
    {
        push_back( item );
    }
}

template< typename T >
Vector< T >::Vector( const Vector& other ) : data_( nullptr ), size_( 0 ), capacity_( 0 )
{
    reallocate( other.capacity_ );
    size_ = other.size_;
    for( size_t i = 0; i < size_; ++i )
    {
        data_[ i ] = other.data_[ i ];
    }
}

template< typename T >
Vector< T >::Vector( Vector&& other ) noexcept : data_( other.data_ ), size_( other.size_ ), capacity_( other.capacity_ )
{
    other.data_ = nullptr;
    other.size_ = 0;
    other.capacity_ = 0;
}

template< typename T >
Vector< T >::Vector( const T& value ) : data_( new T[ value ] ), size_( value ), capacity_( value )
{
    for( size_t i = 0; i < size_; ++i )
    {
        data_[ i ] = value;
    }
}

template< typename T >
Vector< T >::Vector( size_t size, const T& value ) : data_( new T[ size ] ), size_( size ), capacity_( size )
{
    for( size_t i = 0; i < size_; ++i )
    {
        data_[ i ] = value;
    }
}

template< typename T >
Vector< T >::Vector( T* first, T* last )
{
    size_ = last - first;
    capacity_ = size_;
    data_ = new T[ capacity_ ];
    std::copy( first, last, data_ );
}

template< typename T >
Vector< T >::~Vector()
{
    delete [] data_;
}

template< typename T >
Vector< T >& Vector< T >::operator=( const Vector& other )
{
    if( this != &other )
    {
        delete [] data_;
        reallocate( other.capacity_ );
        size_ = other.size_;
        for( size_t i = 0; i < size_; ++i )
        {
            data_[ i ] = other.data_[ i ];
        }
    }

    return *this;
}

template< typename T >
Vector< T >& Vector< T >::operator=( Vector&& other ) noexcept
{
    if( this != &other )
    {
        delete [] data_;
        data_ = other.data_;
        size_ = other.size_;
        capacity_ = other.capacity_;
        other.data_ = nullptr;
        other.size_ = 0;
        other.capacity_ = 0;
    }

    return *this;
}

template< typename T >
T& Vector< T >::operator[]( size_t index )
{
    if( index >= size_ )
    {
        throw std::out_of_range( "Index out of range!" );
    }

    return data_[ index ];
}

template< typename T >
const T& Vector< T >::operator[]( size_t index ) const
{
    if( index >= size_ )
    {
        throw std::out_of_range( "Index out of range!" );
    }

    return data_[ index ];
}

template< typename T >
bool Vector< T >::operator==( const Vector& other ) const
{
    if( size_ != other.size_ )
    {
        return false;
    }
    for( size_t i = 0; i < size_; ++i )
    {
        if( data_[ i ] != other.data_[ i ] )
        {
            return false;
        }
    }

    return true;
}

template< typename T >
bool Vector< T >::operator!=( const Vector& other ) const
{
    return !( *this == other );
}

template< typename T >
void Vector< T >::push_back( const T& value )
{
    if( size_ >= capacity_ )
    {
        reallocate( capacity_ == 0 ? 1 : 2 * capacity_ );
    }

    data_[ size_++ ] = value;
}

template< typename T >
void Vector< T >::push_back( T&& value )
{
    if( size_ >= capacity_ )
    {
        reallocate( capacity_ == 0 ? 1 : 2 * capacity_ );
    }

    data_[ size_++ ] = std::move( value );
}

template< typename T >
void Vector< T >::pop_back()
{
    if( size_ > 0 )
    {
        --size_;
    }
}

template< typename T >
void Vector< T >::clear()
{
    size_ = 0;
}

template< typename T >
size_t Vector< T >::size() const
{
    return size_;
}

template< typename T >
size_t Vector< T >::capacity() const
{
    return capacity_;
}

template< typename T >
bool Vector< T >::empty() const
{
    return size_ == 0;
}

template< typename T >
void Vector< T >::reserve( size_t newCapacity )
{
    if( newCapacity > capacity_ )
    {
        reallocate( newCapacity );
    }
}

template< typename T >
T* Vector< T >::begin()
{
    return data_;
}

template< typename T >
T* Vector< T >::end()
{
    return data_ + size_;
}

template< typename T >
const T* Vector< T >::begin() const
{
    return data_;
}

template< typename T >
const T* Vector< T >::end() const
{
    return data_ + size_;
}

template< typename T >
void Vector< T >::reallocate( size_t newCapacity )
{
    T* newData = new T[ newCapacity ];
    for( size_t i = 0; i < size_; ++i )
    {
        newData[ i ] = std::move( data_[ i ] );
    }
    delete [] data_;
    data_ = newData;
    capacity_ = newCapacity;
}

#endif //VECTOR_HPP
Editor is loading...
Leave a Comment