// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_FIXEDSIZEVECTOR_H
#define EIGEN_FIXEDSIZEVECTOR_H

namespace Eigen {

/** \class MaxSizeVector
  * \ingroup Core
  *
  * \brief The MaxSizeVector class.
  *
  * The %MaxSizeVector provides a subset of std::vector functionality.
  *
  * The goal is to provide basic std::vector operations when using
  * std::vector is not an option (e.g. on GPU or when compiling using
  * FMA/AVX, as this can cause either compilation failures or illegal
  * instruction failures).
  *
  * Beware: The constructors are not API compatible with these of
  * std::vector.
  */
template <typename T>
class MaxSizeVector {
  static const size_t alignment = EIGEN_PLAIN_ENUM_MAX(EIGEN_ALIGNOF(T), sizeof(void*));
 public:
  // Construct a new MaxSizeVector, reserve n elements.
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  explicit MaxSizeVector(size_t n)
      : reserve_(n), size_(0),
        data_(static_cast<T*>(internal::handmade_aligned_malloc(n * sizeof(T), alignment))) {
  }

  // Construct a new MaxSizeVector, reserve and resize to n.
  // Copy the init value to all elements.
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  MaxSizeVector(size_t n, const T& init)
      : reserve_(n), size_(n),
        data_(static_cast<T*>(internal::handmade_aligned_malloc(n * sizeof(T), alignment))) {
    size_t i = 0;
    EIGEN_TRY
    {
      for(; i < size_; ++i) { new (&data_[i]) T(init); }
    }
    EIGEN_CATCH(...)
    {
      // Construction failed, destruct in reverse order:
      for(; (i+1) > 0; --i) { data_[i-1].~T(); }
      internal::handmade_aligned_free(data_);
      EIGEN_THROW;
    }
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  ~MaxSizeVector() {
    for (size_t i = size_; i > 0; --i) {
      data_[i-1].~T();
    }
    internal::handmade_aligned_free(data_);
  }

  void resize(size_t n) {
    eigen_assert(n <= reserve_);
    for (; size_ < n; ++size_) {
      new (&data_[size_]) T;
    }
    for (; size_ > n; --size_) {
      data_[size_-1].~T();
    }
    eigen_assert(size_ == n);
  }

  // Append new elements (up to reserved size).
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  void push_back(const T& t) {
    eigen_assert(size_ < reserve_);
    new (&data_[size_++]) T(t);
  }

  // For C++03 compatibility this only takes one argument
  template<class X>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  void emplace_back(const X& x) {
    eigen_assert(size_ < reserve_);
    new (&data_[size_++]) T(x);
  }


  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  const T& operator[] (size_t i) const {
    eigen_assert(i < size_);
    return data_[i];
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  T& operator[] (size_t i) {
    eigen_assert(i < size_);
    return data_[i];
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  T& back() {
    eigen_assert(size_ > 0);
    return data_[size_ - 1];
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  const T& back() const {
    eigen_assert(size_ > 0);
    return data_[size_ - 1];
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  void pop_back() {
    eigen_assert(size_ > 0);
    data_[--size_].~T();
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  size_t size() const { return size_; }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  bool empty() const { return size_ == 0; }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  T* data() { return data_; }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  const T* data() const { return data_; }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  T* begin() { return data_; }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  T* end() { return data_ + size_; }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  const T* begin() const { return data_; }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
  const T* end() const { return data_ + size_; }

 private:
  size_t reserve_;
  size_t size_;
  T* data_;
};

}  // namespace Eigen

#endif  // EIGEN_FIXEDSIZEVECTOR_H
