
#ifndef PLS_ALIGNED_STACK_IMPL_H
#define PLS_ALIGNED_STACK_IMPL_H

#include <utility>

namespace pls {
namespace internal {
namespace scheduling {
namespace data_structures {

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

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

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

  return *reinterpret_cast<T *>(memory_at_offset(current_offset_));
}

}
}
}
}

#endif //PLS_ALIGNED_STACK_IMPL_H
