| //===-- lib/runtime/array.h -------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef FLANG_RT_RUNTIME_ARRAY_H_ |
| #define FLANG_RT_RUNTIME_ARRAY_H_ |
| |
| #include "flang-rt/runtime/memory.h" |
| #include "flang-rt/runtime/terminator.h" |
| |
| namespace Fortran::runtime { |
| // A simple dynamic array that only supports appending to avoid std::vector. |
| template <typename T> struct DynamicArray { |
| ~DynamicArray() { |
| for (std::size_t i = 0; i < size_; ++i) { |
| data_[i].~T(); |
| } |
| FreeMemory(data_); |
| } |
| |
| void emplace_back(T &&value) { |
| if (size_ == capacity_) { |
| reserve(capacity_ ? capacity_ * 2 : 4); |
| } |
| new (data_ + size_) T(std::move(value)); |
| ++size_; |
| } |
| |
| void reserve(std::size_t newCap) { |
| if (newCap <= capacity_) { |
| return; |
| } |
| T *new_data = static_cast<T *>( |
| AllocateMemoryOrCrash(terminator_, newCap * sizeof(T))); |
| for (std::size_t i = 0; i < size_; ++i) { |
| new (new_data + i) T(std::move(data_[i])); |
| data_[i].~T(); |
| } |
| FreeMemory(data_); |
| data_ = new_data; |
| capacity_ = newCap; |
| } |
| |
| T *begin() const { return data_; } |
| T *end() const { return data_ + size_; } |
| |
| private: |
| T *data_ = nullptr; |
| std::size_t size_ = 0; |
| std::size_t capacity_ = 0; |
| Terminator terminator_{__FILE__, __LINE__}; |
| }; |
| } // namespace Fortran::runtime |
| |
| #endif // FLANG_RT_RUNTIME_ARRAY_H_ |