
#ifndef PLS_ALIGNED_STACK_IMPL_H
#define PLS_ALIGNED_STACK_IMPL_H

#include <utility>

namespace pls {
namespace internal {
namespace data_structures {

template<typename T, typename ...ARGS>
T *aligned_stack::push(ARGS &&... args) {
  return new(push_bytes<T>())T(std::forward<ARGS>(args)...);
}

template<typename T>
char *aligned_stack::push_bytes() {
  return push_bytes(sizeof(T));
}

template<typename T>
void aligned_stack::pop() {
  auto num_cache_lines = base::alignment::next_alignment(sizeof(T)) / base::system_details::CACHE_LINE_SIZE;
  current_offset_ -= num_cache_lines;

  auto result = *reinterpret_cast<T *>(memory_at_offset(current_offset_));
  result.~T();
}

template<size_t SIZE>
static_aligned_stack<SIZE>::static_aligned_stack(): memory_{}, aligned_stack_{memory_.data(), SIZE} {};

}
}
}

#endif //PLS_ALIGNED_STACK_IMPL_H
