C/C++ API Reference
Loading...
Searching...
No Matches
layout.h
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <cstddef>
17
18#include "pw_allocator/hardening.h"
19#include "pw_result/result.h"
20
21namespace pw::allocator {
22namespace internal {
23
24// Helper variables to determine when a template parameter is an array type.
25// Based on the sample implementation found at
26// https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique.
27template <typename>
28constexpr bool is_unbounded_array_v = false;
29
30template <typename T>
31constexpr bool is_unbounded_array_v<T[]> = true;
32
33template <typename>
34constexpr bool is_bounded_array_v = false;
35
36template <typename T, size_t kN>
37constexpr bool is_bounded_array_v<T[kN]> = true;
38
39} // namespace internal
40
42
58class Layout {
59 public:
60 constexpr Layout() : Layout(0) {}
61 constexpr explicit Layout(size_t size)
62 : Layout(size, alignof(std::max_align_t)) {}
63 constexpr Layout(size_t size, size_t alignment)
64 : size_(size), alignment_(alignment) {}
65
67 template <typename T>
68 static constexpr std::enable_if_t<!std::is_array_v<T>, Layout> Of() {
69 return Layout(sizeof(T), alignof(T));
70 }
71
73 template <typename T>
74 static constexpr std::enable_if_t<internal::is_bounded_array_v<T>, Layout>
75 Of() {
76 return Layout(sizeof(T), alignof(std::remove_extent_t<T>));
77 }
78
80 template <typename T>
81 static constexpr std::enable_if_t<internal::is_unbounded_array_v<T>, Layout>
82 Of(size_t count) {
83 using U = std::remove_extent_t<T>;
84 size_t size = sizeof(U);
85 Hardening::Multiply(size, count);
86 return Layout(size, alignof(U));
87 }
88
91 static constexpr Layout Unwrap(const Result<Layout>& result) {
92 return result.ok() ? (*result) : Layout();
93 }
94
95 constexpr Layout Extend(size_t size) const {
96 Hardening::Increment(size, size_);
97 return Layout(size, alignment_);
98 }
99
100 constexpr Layout Align(size_t alignment) const {
101 return Layout(size_, std::max(alignment, alignment_));
102 }
103
104 constexpr size_t size() const { return size_; }
105 constexpr size_t alignment() const { return alignment_; }
106
107 private:
108 size_t size_;
109 size_t alignment_;
110};
111
112inline bool operator==(const Layout& lhs, const Layout& rhs) {
113 return lhs.size() == rhs.size() && lhs.alignment() == rhs.alignment();
114}
115
116inline bool operator!=(const Layout& lhs, const Layout& rhs) {
117 return !(lhs == rhs);
118}
119
121
122} // namespace pw::allocator
Definition: poll.h:25
Definition: layout.h:58
static constexpr Layout Unwrap(const Result< Layout > &result)
Definition: layout.h:91
static constexpr std::enable_if_t< internal::is_bounded_array_v< T >, Layout > Of()
Creates a Layout for the given bounded array type, e.g. Foo[kN].
Definition: layout.h:75
static constexpr std::enable_if_t< internal::is_unbounded_array_v< T >, Layout > Of(size_t count)
Creates a Layout for the given array type, e.g. Foo[].
Definition: layout.h:82
static constexpr std::enable_if_t<!std::is_array_v< T >, Layout > Of()
Creates a Layout for the given type.
Definition: layout.h:68