blob: d41f5f95407e9973cf6c0ea7b44a4f858da6e7de [file] [log] [blame]
peter klausler491122d2020-01-16 13:51:25 -08001//===-- runtime/memory.h ----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// Thin wrapper around malloc()/free() to isolate the dependency,
10// ease porting, and provide an owning pointer.
11
12#ifndef FORTRAN_RUNTIME_MEMORY_H_
13#define FORTRAN_RUNTIME_MEMORY_H_
14
15#include <memory>
16
17namespace Fortran::runtime {
18
19class Terminator;
20
peter klauslerf7be2512020-01-23 16:59:27 -080021[[nodiscard]] void *AllocateMemoryOrCrash(Terminator &, std::size_t bytes);
22template<typename A>[[nodiscard]] A &AllocateOrCrash(Terminator &t) {
peter klausler491122d2020-01-16 13:51:25 -080023 return *reinterpret_cast<A *>(AllocateMemoryOrCrash(t, sizeof(A)));
24}
25void FreeMemory(void *);
peter klauslerf7be2512020-01-23 16:59:27 -080026template<typename A> void FreeMemory(A *p) {
27 FreeMemory(reinterpret_cast<void *>(p));
28}
29template<typename A> void FreeMemoryAndNullify(A *&p) {
30 FreeMemory(p);
31 p = nullptr;
32}
peter klausler491122d2020-01-16 13:51:25 -080033
34template<typename A> struct New {
peter klauslerf7be2512020-01-23 16:59:27 -080035 template<typename... X>
36 [[nodiscard]] A &operator()(Terminator &terminator, X &&... x) {
peter klauslerfae12a02020-01-23 16:10:00 -080037 return *new (AllocateMemoryOrCrash(terminator, sizeof(A)))
38 A{std::forward<X>(x)...};
peter klausler491122d2020-01-16 13:51:25 -080039 }
40};
41
peter klauslerfae12a02020-01-23 16:10:00 -080042template<typename A> struct OwningPtrDeleter {
peter klausler491122d2020-01-16 13:51:25 -080043 void operator()(A *p) { FreeMemory(p); }
44};
peter klausler491122d2020-01-16 13:51:25 -080045
46template<typename A> using OwningPtr = std::unique_ptr<A, OwningPtrDeleter<A>>;
peter klauslerf7be2512020-01-23 16:59:27 -080047
48template<typename A> struct Allocator {
49 using value_type = A;
50 explicit Allocator(Terminator &t) : terminator{t} {}
51 template<typename B>
52 explicit constexpr Allocator(const Allocator<B> &that) noexcept
53 : terminator{that.terminator} {}
54 Allocator(const Allocator &) = default;
55 Allocator(Allocator &&) = default;
56 [[nodiscard]] constexpr A *allocate(std::size_t n) {
57 return reinterpret_cast<A *>(
58 AllocateMemoryOrCrash(terminator, n * sizeof(A)));
59 }
60 constexpr void deallocate(A *p, std::size_t) { FreeMemory(p); }
61 Terminator &terminator;
62};
peter klausler491122d2020-01-16 13:51:25 -080063}
64
65#endif // FORTRAN_RUNTIME_MEMORY_H_