WPILibC++ 2023.4.3-108-ge5452e3
AllocatorBase.h
Go to the documentation of this file.
1//===- AllocatorBase.h - Simple memory allocation abstraction ---*- 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/// \file
9///
10/// This file defines MallocAllocator. MallocAllocator conforms to the LLVM
11/// "Allocator" concept which consists of an Allocate method accepting a size
12/// and alignment, and a Deallocate accepting a pointer and size. Further, the
13/// LLVM "Allocator" concept has overloads of Allocate and Deallocate for
14/// setting size and alignment based on the final type. These overloads are
15/// typically provided by a base class template \c AllocatorBase.
16///
17//===----------------------------------------------------------------------===//
18
19#ifndef WPIUTIL_WPI_ALLOCATORBASE_H
20#define WPIUTIL_WPI_ALLOCATORBASE_H
21
22#include "wpi/Compiler.h"
23#include "wpi/MemAlloc.h"
24#include <type_traits>
25
26namespace wpi {
27
28/// CRTP base class providing obvious overloads for the core \c
29/// Allocate() methods of LLVM-style allocators.
30///
31/// This base class both documents the full public interface exposed by all
32/// LLVM-style allocators, and redirects all of the overloads to a single core
33/// set of methods which the derived class must define.
34template <typename DerivedT> class AllocatorBase {
35public:
36 /// Allocate \a Size bytes of \a Alignment aligned memory. This method
37 /// must be implemented by \c DerivedT.
38 void *Allocate(size_t Size, size_t Alignment) {
39#ifdef __clang__
40 static_assert(static_cast<void *(AllocatorBase::*)(size_t, size_t)>(
42 static_cast<void *(DerivedT::*)(size_t, size_t)>(
43 &DerivedT::Allocate),
44 "Class derives from AllocatorBase without implementing the "
45 "core Allocate(size_t, size_t) overload!");
46#endif
47 return static_cast<DerivedT *>(this)->Allocate(Size, Alignment);
48 }
49
50 /// Deallocate \a Ptr to \a Size bytes of memory allocated by this
51 /// allocator.
52 void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
53#ifdef __clang__
54 static_assert(
55 static_cast<void (AllocatorBase::*)(const void *, size_t, size_t)>(
57 static_cast<void (DerivedT::*)(const void *, size_t, size_t)>(
58 &DerivedT::Deallocate),
59 "Class derives from AllocatorBase without implementing the "
60 "core Deallocate(void *) overload!");
61#endif
62 return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size, Alignment);
63 }
64
65 // The rest of these methods are helpers that redirect to one of the above
66 // core methods.
67
68 /// Allocate space for a sequence of objects without constructing them.
69 template <typename T> T *Allocate(size_t Num = 1) {
70 return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
71 }
72
73 /// Deallocate space for a sequence of objects without constructing them.
74 template <typename T>
75 std::enable_if_t<!std::is_same<std::remove_cv_t<T>, void>::value, void>
76 Deallocate(T *Ptr, size_t Num = 1) {
77 Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T), alignof(T));
78 }
79};
80
81class MallocAllocator : public AllocatorBase<MallocAllocator> {
82public:
83 void Reset() {}
84
85 LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
86 return allocate_buffer(Size, Alignment);
87 }
88
89 // Pull in base class overloads.
91
92 void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
93 deallocate_buffer(const_cast<void *>(Ptr), Size, Alignment);
94 }
95
96 // Pull in base class overloads.
98
99 void PrintStats() const {}
100};
101
102} // namespace wpi
103
104#endif // WPIUTIL_WPI_ALLOCATORBASE_H
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
Definition: Compiler.h:293
This file defines counterparts of C library allocation functions defined in the namespace 'std'.
Definition: core.h:1240
CRTP base class providing obvious overloads for the core Allocate() methods of LLVM-style allocators.
Definition: AllocatorBase.h:34
std::enable_if_t<!std::is_same< std::remove_cv_t< T >, void >::value, void > Deallocate(T *Ptr, size_t Num=1)
Deallocate space for a sequence of objects without constructing them.
Definition: AllocatorBase.h:76
void * Allocate(size_t Size, size_t Alignment)
Allocate Size bytes of Alignment aligned memory.
Definition: AllocatorBase.h:38
T * Allocate(size_t Num=1)
Allocate space for a sequence of objects without constructing them.
Definition: AllocatorBase.h:69
void Deallocate(const void *Ptr, size_t Size, size_t Alignment)
Deallocate Ptr to Size bytes of memory allocated by this allocator.
Definition: AllocatorBase.h:52
Definition: AllocatorBase.h:81
void PrintStats() const
Definition: AllocatorBase.h:99
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, size_t Alignment)
Definition: AllocatorBase.h:85
void Reset()
Definition: AllocatorBase.h:83
void Deallocate(const void *Ptr, size_t Size, size_t Alignment)
Definition: AllocatorBase.h:92
Definition: AprilTagFieldLayout.h:18
void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment)
Deallocate a buffer of memory with the given size and alignment.
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * allocate_buffer(size_t Size, size_t Alignment)
Allocate a buffer of memory with the given size and alignment.