13#ifndef FORTRAN_RUNTIME_STACK_H
14#define FORTRAN_RUNTIME_STACK_H
16#include "terminator.h"
17#include "flang/Runtime/memory.h"
19namespace Fortran::runtime {
22 RT_API_ATTRS
void *getElement(
unsigned i) {
29 RT_API_ATTRS
const void *getElement(
unsigned i)
const {
41 alignas(T)
char storage[N][
sizeof(T)];
46 RT_API_ATTRS
void *getElement(
unsigned) {
return nullptr; }
47 RT_API_ATTRS
const void *getElement(
unsigned)
const {
return nullptr; }
61 RT_API_ATTRS
void push(
const T &
object) {
62 if (
void *ptr{this->getElement(size_)}) {
65 top_ =
New<List>{terminator_}(top_, object).release();
69 RT_API_ATTRS
void push(T &&
object) {
70 if (
void *ptr{this->getElement(size_)}) {
71 new (ptr) T{std::move(
object)};
73 top_ =
New<List>{terminator_}(top_, std::move(
object)).release();
77 template <
typename... Args> RT_API_ATTRS
void emplace(Args &&...args) {
78 if (
void *ptr{this->getElement(size_)}) {
79 new (ptr) T{std::forward<Args>(args)...};
82 New<List>{terminator_}(top_, std::forward<Args>(args)...).release();
86 RT_API_ATTRS T &top() {
87 RUNTIME_CHECK(terminator_, size_ > 0);
88 if (
void *ptr{this->getElement(size_ - 1)}) {
89 return *
reinterpret_cast<T *
>(ptr);
91 RUNTIME_CHECK(terminator_, top_);
95 RT_API_ATTRS
const T &top()
const {
96 RUNTIME_CHECK(terminator_, size_ > 0);
97 if (
void *ptr{this->getElement(size_ - 1)}) {
98 return *
reinterpret_cast<const T *
>(ptr);
100 RUNTIME_CHECK(terminator_, top_);
101 return top_->object_;
104 RT_API_ATTRS
void pop() {
105 RUNTIME_CHECK(terminator_, size_ > 0);
106 if (
void *ptr{this->getElement(size_ - 1)}) {
107 reinterpret_cast<T *
>(ptr)->~T();
109 RUNTIME_CHECK(terminator_, top_);
110 List *next{top_->next_};
117 RT_API_ATTRS
bool empty()
const {
return size_ == 0; }
121 template <
typename... Args>
122 RT_API_ATTRS List(List *next, Args &&...args)
123 : next_(next), object_(std::forward<Args>(args)...) {}
124 RT_API_ATTRS List(List *next,
const T &
object)
125 : next_(next), object_(
object) {}
126 RT_API_ATTRS List(List *next, T &&
object)
127 : next_(next), object_(std::move(
object)) {}
128 List *next_{
nullptr};
132 std::size_t size_{0};
Definition: terminator.h:23