/*
 * MVKVector.h
 *
 * Copyright (c) 2012-2019 Dr. Torsten Hans (hans@ipacs.de)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

//
// in case MVKVector should use std::vector
//
#if 0

template<typename T, size_t N = 0>
using MVKVectorInline = std::vector<T>;

template<typename T>
using MVKVectorDefault = std::vector<T>;

template<typename T>
using MVKVector = std::vector<T>;

#else

//
// MVKVector.h is a sequence container that (optionally) implements a small
// buffer optimization.
// It behaves similarly to std::vector, except until a certain number of
// elements are reserved, it does not use the heap.
// Like std::vector, MVKVector is guaranteed to use contiguous memory, so if the
// preallocated number of elements are exceeded, all elements are then in heap.
// MVKVector supports just the necessary members to be compatible with MoltenVK
// If C++17 will be the default in the future, code can be simplified quite a bit.
//
// Example:
//
//  MVKVectorInline<int, 3> vector;
//  vector.emplace_back( 1 );
//  vector.emplace_back( 2 );
//  vector.emplace_back( 3 );
//  // adding another element now reserves memory from heap
//  vector.emplace_back( 4 );
//
// If you don't need any inline storage use
//  MVKVectorDefault<int> vector;   // this is essentially the same as using std::vector
//
// Passing MVKVectorInline to a function would require to use the same template
// parameters that have been used for declaration. To avoid this MVKVectorInline
// is derived from MVKVector. If you want to pass MVKVectorInline to a function
// use MVKVector.
//
#include "MVKVectorAllocator.h"
#include <type_traits>
#include <initializer_list>
#include <utility>


template<class Type> class MVKVector
{
  mvk_vector_allocator_base<Type> *alc_ptr;

public:
  class iterator : public std::iterator<std::forward_iterator_tag, Type>
  {
    const MVKVector *vector;
    size_t           index;

  public:
    iterator() = delete;
    iterator( const size_t _index, const MVKVector &_vector ) : vector{ &_vector }, index{ _index } { }
    iterator &operator=( const iterator &it ) = delete;

    Type *operator->() const { return &vector->alc_ptr->ptr[index]; }
    Type &operator*()  const { return  vector->alc_ptr->ptr[index]; }
    operator Type*( )  const { return &vector->alc_ptr->ptr[index]; }

    bool operator==( const iterator &it ) const { return vector == it.vector && index == it.index; }
    bool operator!=( const iterator &it ) const { return vector != it.vector || index != it.index; }

    iterator& operator++()      {                 ++index; return *this; }
    iterator  operator++( int ) { auto t = *this; ++index; return t; }

    bool   is_valid()     const { return index < vector->size(); }
    size_t get_position() const { return index; }
  };

public:
  typedef Type value_type;

  MVKVector() = delete;
  MVKVector( mvk_vector_allocator_base<Type> *a ) : alc_ptr{ a } { }
  virtual ~MVKVector() { }

  iterator begin() const { return iterator( 0,               *this ); }
  iterator end()   const { return iterator( alc_ptr->size(), *this ); }

  virtual const Type &operator[]( const size_t i ) const                  = 0;
  virtual       Type &operator[]( const size_t i )                        = 0;
  virtual const Type &at( const size_t i ) const                          = 0;
  virtual       Type &at( const size_t i )                                = 0;
  virtual const Type &front() const                                       = 0;
  virtual       Type &front()                                             = 0;
  virtual const Type &back() const                                        = 0;
  virtual       Type &back()                                              = 0;
  virtual const Type *data() const                                        = 0;
  virtual       Type *data()                                              = 0;

  virtual size_t      size()     const                                    = 0;
  virtual bool        empty()    const                                    = 0;
  virtual size_t      capacity() const                                    = 0;

  virtual void        pop_back()                                          = 0;
  virtual void        clear()                                             = 0;
  virtual void        reset()                                             = 0;
  virtual void        reserve( const size_t new_size )                    = 0;
  virtual void        assign( const size_t new_size, const Type &t )      = 0;
  virtual void        resize( const size_t new_size, const Type t = { } ) = 0;
  virtual void        shrink_to_fit()                                     = 0;
  virtual void        push_back( const Type &t )                          = 0;
  virtual void        push_back( Type &&t )                               = 0;
};


template<class Type> class MVKVector<Type *>
{
  mvk_vector_allocator_base<Type*> *alc_ptr;

  class iterator : public std::iterator<std::forward_iterator_tag, Type*>
  {
    const MVKVector *vector;
    size_t           index;

  public:
    iterator() = delete;
    iterator( const size_t _index, const MVKVector &_vector ) : vector{ &_vector }, index{ _index } { }
    iterator &operator=( const iterator &it ) = delete;

    Type *operator->() const { return vector->alc_ptr->ptr[index]; }
    Type *&operator*()       { return vector->alc_ptr->ptr[index]; }
    operator Type*&()  const { return &vector->alc_ptr->ptr[index]; }

    bool operator==( const iterator &it ) const { return vector == it.vector && index == it.index; }
    bool operator!=( const iterator &it ) const { return vector != it.vector || index != it.index; }

    iterator& operator++()      {                 ++index; return *this; }
    iterator  operator++( int ) { auto t = *this; ++index; return t; }

    bool   is_valid()     const { return index < vector->size(); }
    size_t get_position() const { return index; }
  };

public:
  typedef Type* value_type;

  MVKVector() = delete;
  MVKVector( mvk_vector_allocator_base<Type*> *a ) : alc_ptr{ a } { }
  virtual ~MVKVector() { }

  iterator begin() const { return iterator( 0,               *this ); }
  iterator end()   const { return iterator( alc_ptr->size(), *this ); }

  virtual const Type * const  operator[]( const size_t i ) const             = 0;
  virtual       Type *       &operator[]( const size_t i )                   = 0;
  virtual const Type * const  at( const size_t i ) const                     = 0;
  virtual       Type *       &at( const size_t i )                           = 0;
  virtual const Type * const  front() const                                  = 0;
  virtual       Type *       &front()                                        = 0;
  virtual const Type * const  back() const                                   = 0;
  virtual       Type *       &back()                                         = 0;
  virtual const Type * const *data() const                                   = 0;
  virtual       Type *       *data()                                         = 0;

  virtual size_t              size() const                                   = 0;
  virtual bool                empty() const                                  = 0;
  virtual size_t              capacity() const                               = 0;

  virtual void                pop_back()                                     = 0;
  virtual void                clear()                                        = 0;
  virtual void                reset()                                        = 0;
  virtual void                reserve( const size_t new_size )               = 0;
  virtual void                assign( const size_t new_size, const Type *t ) = 0;
  virtual void                resize( const size_t new_size, const Type *t ) = 0;
  virtual void                shrink_to_fit()                                = 0;
  virtual void                push_back( const Type *t )                     = 0;
};


// this is the actual implementation of MVKVector
template<class Type, typename Allocator = mvk_vector_allocator_default<Type>> class MVKVectorImpl : public MVKVector<Type>
{
  friend class MVKVectorImpl;

  Allocator  alc;
  
public:
  class iterator : public std::iterator<std::forward_iterator_tag, Type>
  {
    const MVKVectorImpl *vector;
    size_t               index;

  public:
    iterator() = delete;
    iterator( const size_t _index, const MVKVectorImpl &_vector ) : vector{ &_vector }, index{ _index } { }

    iterator &operator=( const iterator &it )
    {
      vector = it.vector;
      index  = it.index;
      return *this;
    }

    Type *operator->() { return &vector->alc.ptr[index]; }
    Type &operator*()  { return  vector->alc.ptr[index]; }
    operator Type*()   { return &vector->alc.ptr[index]; }

    bool operator==( const iterator &it ) const { return vector == it.vector && index == it.index; }
    bool operator!=( const iterator &it ) const { return vector != it.vector || index != it.index; }

    iterator& operator++()      {                 ++index; return *this; }
    iterator  operator++( int ) { auto t = *this; ++index; return t; }

    bool   is_valid()     const { return index < vector->alc.size(); }
    size_t get_position() const { return index; }
  };

private:
  // this is the growth strategy -> adjust to your needs
  size_t vector_GetNextCapacity() const
  {
    constexpr auto ELEMENTS_FOR_64_BYTES = 64 / sizeof( Type );
    constexpr auto MINIMUM_CAPACITY = ELEMENTS_FOR_64_BYTES > 4 ? ELEMENTS_FOR_64_BYTES : 4;
    const auto current_capacity = capacity();
    return MINIMUM_CAPACITY + ( 3 * current_capacity ) / 2;
  }

  void vector_Allocate( const size_t s )
  {
    const auto new_reserved_size = s > size() ? s : size();

    alc.allocate( new_reserved_size );
  }

  void vector_ReAllocate( const size_t s )
  {
    alc.re_allocate( s );
  }

public:
  MVKVectorImpl() : MVKVector<Type>{ &alc }
  {
  }

  MVKVectorImpl( const size_t n, const Type t ) : MVKVector<Type>{ &alc }
  {
    if( n > 0 )
    {
      alc.allocate( n );

      for( size_t i = 0; i < n; ++i )
      {
        alc.construct( &alc.ptr[i], t );
      }

      alc.num_elements_used = n;
    }
  }

  MVKVectorImpl( const MVKVectorImpl &a ) : MVKVector<Type>{ &alc }
  {
    const size_t n = a.size();

    if( n > 0 )
    {
      alc.allocate( n );

      for( size_t i = 0; i < n; ++i )
      {
        alc.construct( &alc.ptr[i], a.alc.ptr[i] );
      }

      alc.num_elements_used = n;
    }
  }

  template<typename U>
  MVKVectorImpl( const U &a ) : MVKVector<Type>{ &alc }
  {
    const size_t n = a.size();

    if( n > 0 )
    {
      alc.allocate( n );

      for( size_t i = 0; i < n; ++i )
      {
        alc.construct( &alc.ptr[i], a[i] );
      }

      alc.num_elements_used = n;
    }
  }

  MVKVectorImpl( MVKVectorImpl &&a ) : MVKVector<Type>{ &alc }, alc{ std::move( a.alc ) }
  {
  }

  MVKVectorImpl( std::initializer_list<Type> vector ) : MVKVector<Type>{ &alc }
  {
    if( vector.size() > capacity() )
    {
      vector_Allocate( vector.size() );
    }

    // std::initializer_list does not yet support std::move, we use it anyway but it has no effect
    for( auto &&element : vector )
    {
      alc.construct( &alc.ptr[alc.num_elements_used], std::move( element ) );
      ++alc.num_elements_used;
    }
  }

  ~MVKVectorImpl()
  {
  }

  template<typename U>
  MVKVectorImpl& operator=( const U &a )
  {
    static_assert( std::is_base_of<MVKVector<Type>, U>::value, "argument is not of type MVKVector" );

    if( this != reinterpret_cast<const MVKVector<Type>*>( &a ) )
    {
      const auto n = a.size();

      if( alc.num_elements_used == n )
      {
        for( size_t i = 0; i < n; ++i )
        {
          alc.ptr[i] = a.alc.ptr[i];
        }
      }
      else
      {
        if( n > capacity() )
        {
          vector_ReAllocate( n );
        }
        else
        {
          alc.template destruct_all<Type>();
        }

        for( size_t i = 0; i < n; ++i )
        {
          alc.construct( &alc.ptr[i], a[i] );
        }

        alc.num_elements_used = n;
      }
    }

    return *this;
  }

  MVKVectorImpl& operator=( MVKVectorImpl &&a )
  {
    alc.swap( a.alc );
    return *this;
  }

  bool operator==( const MVKVectorImpl &a ) const
  {
    if( alc.num_elements_used != a.alc.num_elements_used )
      return false;
    for( size_t i = 0; i < alc.num_elements_used; ++i )
    {
      if( alc[i] != a.alc[i] )
        return false;
    }
    return true;
  }

  bool operator!=( const MVKVectorImpl &a ) const
  {
    if( alc.num_elements_used != a.alc.num_elements_used )
      return true;
    for( size_t i = 0; i < alc.num_elements_used; ++i )
    {
      if( alc.ptr[i] != a.alc[i] )
        return true;
    }
    return false;
  }

  void swap( MVKVectorImpl &a )
  {
    alc.swap( a.alc );
  }

  iterator begin() const { return iterator( 0, *this ); }
  iterator end()   const { return iterator( alc.num_elements_used, *this ); }

  const Type &operator[]( const size_t i ) const override { return alc[i]; }
        Type &operator[]( const size_t i )       override { return alc[i]; }
  const Type &at( const size_t i )         const override { return alc[i]; }
        Type &at( const size_t i )               override { return alc[i]; }
  const Type &front()                      const override { return alc[0]; }
        Type &front()                            override { return alc[0]; }
  const Type &back()                       const override { return alc[alc.num_elements_used - 1]; }
        Type &back()                             override { return alc[alc.num_elements_used - 1]; }
  const Type *data()                       const override { return alc.ptr; }
        Type *data()                             override { return alc.ptr; }

  size_t      size()                       const override { return alc.num_elements_used; }
  bool        empty()                      const override { return alc.num_elements_used == 0; }
  size_t      capacity()                   const override { return alc.get_capacity(); }

  void pop_back() override
  {
    if( alc.num_elements_used > 0 )
    {
      --alc.num_elements_used;
      alc.destruct( &alc.ptr[alc.num_elements_used] );
    }
  }

  void clear() override
  {
    alc.template destruct_all<Type>();
  }

  void reset() override
  {
    alc.deallocate();
  }

  void reserve( const size_t new_size ) override
  {
    if( new_size > capacity() )
    {
      vector_ReAllocate( new_size );
    }
  }

  void assign( const size_t new_size, const Type &t ) override
  {
    if( new_size <= capacity() )
    {
      clear();
    }
    else
    {
      vector_Allocate( new_size );
    }

    for( size_t i = 0; i < new_size; ++i )
    {
      alc.construct( &alc.ptr[i], t );
    }

    alc.num_elements_used = new_size;
  }

  template <class InputIterator>
  void assign( InputIterator first, InputIterator last )
  {
    clear();

    while( first != last )
    {
      emplace_back( *first );
      ++first;
    }
  }

  void resize( const size_t new_size, const Type t = { } ) override
  {
    if( new_size == alc.num_elements_used )
    {
      return;
    }

    if( new_size == 0 )
    {
      clear();
      return;
    }

    if( new_size > alc.num_elements_used )
    {
      if( new_size > capacity() )
      {
        vector_ReAllocate( new_size );
      }

      while( alc.num_elements_used < new_size )
      {
        alc.construct( &alc.ptr[alc.num_elements_used], t );
        ++alc.num_elements_used;
      }
    }
    else
    {
      //if constexpr( !std::is_trivially_destructible<Type>::value )
      {
        while( alc.num_elements_used > new_size )
        {
          --alc.num_elements_used;
          alc.destruct( &alc.ptr[alc.num_elements_used] );
        }
      }
      //else
      //{
      //  alc.num_elements_used = new_size;
      //}
    }
  }

  // trims the capacity of the slist to the number of alc.ptr
  void shrink_to_fit() override
  {
    alc.shrink_to_fit();
  }

  void erase( const iterator it )
  {
    if( it.is_valid() )
    {
      --alc.num_elements_used;

      for( size_t i = it.get_position(); i < alc.num_elements_used; ++i )
      {
        alc.ptr[i] = std::move( alc.ptr[i + 1] );
      }

      // this is required for types with a destructor
      alc.destruct( &alc.ptr[alc.num_elements_used] );
    }
  }

  void erase( const iterator first, const iterator last )
  {
    if( first.is_valid() )
    {
      size_t last_pos = last.is_valid() ? last.get_position() : size();
      size_t n = last_pos - first.get_position();
      alc.num_elements_used -= n;

      for( size_t i = first.get_position(), e = last_pos; i < alc.num_elements_used && e < alc.num_elements_used + n; ++i, ++e )
      {
        alc.ptr[i] = std::move( alc.ptr[e] );
      }

      // this is required for types with a destructor
      for( size_t i = alc.num_elements_used; i < alc.num_elements_used + n; ++i )
      {
        alc.destruct( &alc.ptr[i] );
      }
    }
  }

  // adds t before it and automatically resizes vector if necessary
  void insert( const iterator it, Type t )
  {
    if( !it.is_valid() || alc.num_elements_used == 0 )
    {
      push_back( std::move( t ) );
    }
    else
    {
      if( alc.num_elements_used == capacity() )
        vector_ReAllocate( vector_GetNextCapacity() );

      // move construct last element
      alc.construct( &alc.ptr[alc.num_elements_used], std::move( alc.ptr[alc.num_elements_used - 1] ) );

      // move the remaining elements
      const size_t it_position = it.get_position();
      for( size_t i = alc.num_elements_used - 1; i > it_position; --i )
      {
        alc.ptr[i] = std::move( alc.ptr[i - 1] );
      }

      alc.ptr[it_position] = std::move( t );
      ++alc.num_elements_used;
    }
  }

  void push_back( const Type &t ) override
  {
    if( alc.num_elements_used == capacity() )
      vector_ReAllocate( vector_GetNextCapacity() );

    alc.construct( &alc.ptr[alc.num_elements_used], t );
    ++alc.num_elements_used;
  }

  void push_back( Type &&t ) override
  {
    if( alc.num_elements_used == capacity() )
      vector_ReAllocate( vector_GetNextCapacity() );

    alc.construct( &alc.ptr[alc.num_elements_used], std::forward<Type>( t ) );
    ++alc.num_elements_used;
  }

  template<class... Args>
  Type &emplace_back( Args&&... args )
  {
    if( alc.num_elements_used == capacity() )
      vector_ReAllocate( vector_GetNextCapacity() );

    alc.construct( &alc.ptr[alc.num_elements_used], std::forward<Args>( args )... );
    ++alc.num_elements_used;

    return alc.ptr[alc.num_elements_used - 1];
  }
};

// specialization for pointer types
template<class Type, typename Allocator> class MVKVectorImpl<Type*, Allocator> : public MVKVector<Type*>
{
  friend class MVKVectorImpl;

  Allocator  alc;

public:
  class iterator : public std::iterator<std::forward_iterator_tag, Type*>
  {
    MVKVectorImpl *vector;
    size_t         index;

  public:
    iterator() = delete;
    iterator( const size_t _index, MVKVectorImpl &_vector ) : vector{ &_vector }, index{ _index } { }

    iterator &operator=( const iterator &it )
    {
      vector = it.vector;
      index = it.index;
      return *this;
    }

    Type *&operator*() { return vector->alc[index]; }

    bool operator==( const iterator &it ) const { return vector == it.vector && index == it.index; }
    bool operator!=( const iterator &it ) const { return vector != it.vector || index != it.index; }

    iterator& operator++() { ++index; return *this; }
    iterator  operator++( int ) { auto t = *this; ++index; return t; }

    bool   is_valid()     const { return index < vector->alc.size(); }
    size_t get_position() const { return index; }
  };

private:
  // this is the growth strategy -> adjust to your needs
  size_t vector_GetNextCapacity() const
  {
    constexpr auto ELEMENTS_FOR_64_BYTES = 64 / sizeof( Type* );
    constexpr auto MINIMUM_CAPACITY = ELEMENTS_FOR_64_BYTES > 4 ? ELEMENTS_FOR_64_BYTES : 4;
    const auto current_capacity = capacity();
    return MINIMUM_CAPACITY + ( 3 * current_capacity ) / 2;
  }

  void vector_Allocate( const size_t s )
  {
    const auto new_reserved_size = s > size() ? s : size();

    alc.allocate( new_reserved_size );
  }

  void vector_ReAllocate( const size_t s )
  {
    alc.re_allocate( s );
  }

public:
  MVKVectorImpl() : MVKVector<Type*>{ &alc }
  {
  }

  MVKVectorImpl( const size_t n, const Type *t ) : MVKVector<Type*>{ &alc }
  {
    if ( n > 0 )
    {
      alc.allocate( n );

      for ( size_t i = 0; i < n; ++i )
      {
        alc.ptr[i] = t;
      }

      alc.num_elements_used = n;
    }
  }

  MVKVectorImpl( const MVKVectorImpl &a ) : MVKVector<Type*>{ &alc }
  {
    const size_t n = a.size();

    if ( n > 0 )
    {
      alc.allocate( n );

      for ( size_t i = 0; i < n; ++i )
      {
        alc.ptr[i] = a.alc.ptr[i];
      }

      alc.num_elements_used = n;
    }
  }

  MVKVectorImpl( MVKVectorImpl &&a ) : MVKVector<Type*>{ &alc }, alc{ std::move( a.alc ) }
  {
  }

  MVKVectorImpl( std::initializer_list<Type*> vector ) : MVKVector<Type*>{ &alc }
  {
    if ( vector.size() > capacity() )
    {
      vector_Allocate( vector.size() );
    }

    // std::initializer_list does not yet support std::move, we use it anyway but it has no effect
    for ( auto element : vector )
    {
      alc.ptr[alc.num_elements_used] = element;
      ++alc.num_elements_used;
    }
  }

  ~MVKVectorImpl()
  {
  }

  template<typename U>
  MVKVectorImpl& operator=( const U &a )
  {
    static_assert( std::is_base_of<MVKVector<U>, U>::value, "argument is not of type MVKVector" );

    if ( this != reinterpret_cast< const MVKVector<Type>* >( &a ) )
    {
      const auto n = a.size();

      if ( alc.num_elements_used == n )
      {
        for ( size_t i = 0; i < n; ++i )
        {
          alc.ptr[i] = a.alc.ptr[i];
        }
      }
      else
      {
        if ( n > capacity() )
        {
          vector_ReAllocate( n );
        }

        for ( size_t i = 0; i < n; ++i )
        {
          alc.ptr[i] = a[i];
        }

        alc.num_elements_used = n;
      }
    }

    return *this;
  }

  MVKVectorImpl& operator=( MVKVectorImpl &&a )
  {
    alc.swap( a.alc );
    return *this;
  }

  bool operator==( const MVKVectorImpl &a ) const
  {
    if ( alc.num_elements_used != a.alc.num_elements_used )
      return false;
    for ( size_t i = 0; i < alc.num_elements_used; ++i )
    {
      if ( alc[i] != a.alc[i] )
        return false;
    }
    return true;
  }

  bool operator!=( const MVKVectorImpl &a ) const
  {
    if ( alc.num_elements_used != a.alc.num_elements_used )
      return true;
    for ( size_t i = 0; i < alc.num_elements_used; ++i )
    {
      if ( alc.ptr[i] != a.alc[i] )
        return true;
    }
    return false;
  }

  void swap( MVKVectorImpl &a )
  {
    alc.swap( a.alc );
  }

  iterator begin()        { return iterator( 0, *this ); }
  iterator end()          { return iterator( alc.num_elements_used, *this ); }

  const Type * const  at( const size_t i )         const override { return alc[i]; }
        Type *       &at( const size_t i )               override { return alc[i]; }
  const Type * const  operator[]( const size_t i ) const override { return alc[i]; }
        Type *       &operator[]( const size_t i )       override { return alc[i]; }
  const Type * const  front()                      const override { return alc[0]; }
        Type *       &front()                            override { return alc[0]; }
  const Type * const  back()                       const override { return alc[alc.num_elements_used - 1]; }
        Type *       &back()                             override { return alc[alc.num_elements_used - 1]; }
  const Type * const *data()                       const override { return alc.ptr; }
        Type *       *data()                             override { return alc.ptr; }

  size_t   size()                                  const override { return alc.num_elements_used; }
  bool     empty()                                 const override { return alc.num_elements_used == 0; }
  size_t   capacity()                              const override { return alc.get_capacity(); }

  void pop_back() override
  {
    if ( alc.num_elements_used > 0 )
    {
      --alc.num_elements_used;
    }
  }

  void clear() override
  {
    alc.num_elements_used = 0;
  }

  void reset() override
  {
    alc.deallocate();
  }

  void reserve( const size_t new_size ) override
  {
    if ( new_size > capacity() )
    {
      vector_ReAllocate( new_size );
    }
  }

  void assign( const size_t new_size, const Type *t ) override
  {
    if ( new_size <= capacity() )
    {
      clear();
    }
    else
    {
      vector_Allocate( new_size );
    }

    for ( size_t i = 0; i < new_size; ++i )
    {
      alc.ptr[i] = const_cast< Type* >( t );
    }

    alc.num_elements_used = new_size;
  }

  void resize( const size_t new_size, const Type *t ) override
  {
    if ( new_size == alc.num_elements_used )
    {
      return;
    }

    if ( new_size == 0 )
    {
      clear();
      return;
    }

    if ( new_size > alc.num_elements_used )
    {
      if ( new_size > capacity() )
      {
        vector_ReAllocate( new_size );
      }

      while ( alc.num_elements_used < new_size )
      {
        alc.ptr[alc.num_elements_used] = const_cast< Type* >( t );
        ++alc.num_elements_used;
      }
    }
    else
    {
      alc.num_elements_used = new_size;
    }
  }

  // trims the capacity of the MVKVector to the number of used elements
  void shrink_to_fit() override
  {
    alc.shrink_to_fit();
  }

  void erase( const iterator it )
  {
    if ( it.is_valid() )
    {
      --alc.num_elements_used;

      for ( size_t i = it.get_position(); i < alc.num_elements_used; ++i )
      {
        alc.ptr[i] = alc.ptr[i + 1];
      }
    }
  }

  void erase( const iterator first, const iterator last )
  {
    if( first.is_valid() )
    {
      size_t last_pos = last.is_valid() ? last.get_position() : size();
      size_t n = last_pos - first.get_position();
      alc.num_elements_used -= n;

      for( size_t i = first.get_position(), e = last_pos; i < alc.num_elements_used && e < alc.num_elements_used + n; ++i, ++e )
      {
        alc.ptr[i] = alc.ptr[e];
      }
    }
  }

  // adds t before position it and automatically resizes vector if necessary
  void insert( const iterator it, const Type *t )
  {
    if ( !it.is_valid() || alc.num_elements_used == 0 )
    {
      push_back( t );
    }
    else
    {
      if ( alc.num_elements_used == capacity() )
        vector_ReAllocate( vector_GetNextCapacity() );

      // move the remaining elements
      const size_t it_position = it.get_position();
      for ( size_t i = alc.num_elements_used; i > it_position; --i )
      {
        alc.ptr[i] = alc.ptr[i - 1];
      }

      alc.ptr[it_position] = const_cast< Type* >( t );
      ++alc.num_elements_used;
    }
  }

  void push_back( const Type *t ) override
  {
    if ( alc.num_elements_used == capacity() )
      vector_ReAllocate( vector_GetNextCapacity() );

    alc.ptr[alc.num_elements_used] = const_cast< Type* >( t );
    ++alc.num_elements_used;
  }
};


template<typename Type>
using MVKVectorDefault = MVKVectorImpl<Type, mvk_vector_allocator_default<Type>>;

template<typename Type, size_t N = 8>
using MVKVectorInline  = MVKVectorImpl<Type, mvk_vector_allocator_with_stack<Type, N>>;


#endif


