blob: 1bd5bca1b78af122df458fce2f1dd4092db91fd2 [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 klausler95696d52020-02-04 16:55:45 -080021[[nodiscard]] void *AllocateMemoryOrCrash(
22 const Terminator &, std::size_t bytes);
23template<typename A>[[nodiscard]] A &AllocateOrCrash(const Terminator &t) {
peter klausler491122d2020-01-16 13:51:25 -080024 return *reinterpret_cast<A *>(AllocateMemoryOrCrash(t, sizeof(A)));
25}
26void FreeMemory(void *);
peter klauslerf7be2512020-01-23 16:59:27 -080027template<typename A> void FreeMemory(A *p) {
28 FreeMemory(reinterpret_cast<void *>(p));
29}
30template<typename A> void FreeMemoryAndNullify(A *&p) {
31 FreeMemory(p);
32 p = nullptr;
33}
peter klausler491122d2020-01-16 13:51:25 -080034
35template<typename A> struct New {
peter klauslerf7be2512020-01-23 16:59:27 -080036 template<typename... X>
peter klausler95696d52020-02-04 16:55:45 -080037 [[nodiscard]] A &operator()(const Terminator &terminator, X &&... x) {
peter klauslerfae12a02020-01-23 16:10:00 -080038 return *new (AllocateMemoryOrCrash(terminator, sizeof(A)))
39 A{std::forward<X>(x)...};
peter klausler491122d2020-01-16 13:51:25 -080040 }
41};
42
peter klauslerfae12a02020-01-23 16:10:00 -080043template<typename A> struct OwningPtrDeleter {
peter klausler491122d2020-01-16 13:51:25 -080044 void operator()(A *p) { FreeMemory(p); }
45};
peter klausler491122d2020-01-16 13:51:25 -080046
47template<typename A> using OwningPtr = std::unique_ptr<A, OwningPtrDeleter<A>>;
peter klauslerf7be2512020-01-23 16:59:27 -080048
49template<typename A> struct Allocator {
50 using value_type = A;
peter klausler95696d52020-02-04 16:55:45 -080051 explicit Allocator(const Terminator &t) : terminator{t} {}
peter klauslerf7be2512020-01-23 16:59:27 -080052 template<typename B>
53 explicit constexpr Allocator(const Allocator<B> &that) noexcept
54 : terminator{that.terminator} {}
55 Allocator(const Allocator &) = default;
56 Allocator(Allocator &&) = default;
57 [[nodiscard]] constexpr A *allocate(std::size_t n) {
58 return reinterpret_cast<A *>(
59 AllocateMemoryOrCrash(terminator, n * sizeof(A)));
60 }
61 constexpr void deallocate(A *p, std::size_t) { FreeMemory(p); }
peter klausler95696d52020-02-04 16:55:45 -080062 const Terminator &terminator;
peter klauslerf7be2512020-01-23 16:59:27 -080063};
peter klausler491122d2020-01-16 13:51:25 -080064}
65
66#endif // FORTRAN_RUNTIME_MEMORY_H_