Program Listing for File aligned.h

Return to documentation for file (src/translator/aligned.h)

#pragma once
#include <cstdlib>
#include <new>
#ifdef _MSC_VER
#include <malloc.h>
#endif

// Aligned simple vector.

namespace marian {
namespace bergamot {

template <class T> class AlignedVector {
public:
  AlignedVector() : mem_(nullptr), size_(0) {}

  explicit AlignedVector(std::size_t size, std::size_t alignment = 64 /* CPU cares about this */)
          : size_(size) {
#ifdef _MSC_VER
    mem_ = static_cast<T*>(_aligned_malloc(size * sizeof(T), alignment));
      if (!mem_) throw std::bad_alloc();
#else
    if (posix_memalign(reinterpret_cast<void **>(&mem_), alignment, size * sizeof(T))) {
      throw std::bad_alloc();
    }
#endif
  }

  AlignedVector(AlignedVector &&from) : mem_(from.mem_), size_(from.size_) {
    from.mem_ = nullptr;
    from.size_ = 0;
  }

  AlignedVector &operator=(AlignedVector &&from) {
    mem_ = from.mem_;
    size_ = from.size_;
    from.mem_ = nullptr;
    from.size_ = 0;
    return *this;
  }

  AlignedVector(const AlignedVector&) = delete;
  AlignedVector& operator=(const AlignedVector&) = delete;

  ~AlignedVector() {
#ifdef _MSC_VER
    _aligned_free(mem_);
#else
    std::free(mem_);
#endif
  }

  std::size_t size() const { return size_; }

  T &operator[](std::size_t offset) { return mem_[offset]; }
  const T &operator[](std::size_t offset) const { return mem_[offset]; }

  T *begin() { return mem_; }
  const T *begin() const { return mem_; }
  T *end() { return mem_ + size_; }
  const T *end() const { return mem_ + size_; }

  template <typename ReturnType>
  ReturnType *as() { return reinterpret_cast<ReturnType*>(mem_); }

private:
  T *mem_;
  std::size_t size_;
};
} // namespace bergamot
} // namespace marian