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#include <type_traits>
18
19#include "pw_allocator/hardening.h"
20#include "pw_result/result.h"
21
22namespace pw {
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>
28struct is_unbounded_array : std::false_type {};
29
30template <typename T>
31struct is_unbounded_array<T[]> : std::true_type {};
32
33template <typename T>
34constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value;
35
36template <typename>
37struct is_bounded_array : std::false_type {};
38
39template <typename T, size_t kN>
40struct is_bounded_array<T[kN]> : std::true_type {};
41
42template <typename T>
43constexpr bool is_bounded_array_v = is_bounded_array<T>::value;
44
45namespace allocator {
46
48
64class Layout {
65 public:
66 constexpr Layout() : Layout(0) {}
67 constexpr explicit Layout(size_t size)
68 : Layout(size, alignof(std::max_align_t)) {}
69 constexpr Layout(size_t size, size_t alignment)
70 : size_(size), alignment_(alignment) {}
71
72 constexpr size_t size() const { return size_; }
73 constexpr size_t alignment() const { return alignment_; }
74
76 template <typename T, std::enable_if_t<!std::is_array_v<T>, int> = 0>
77 static constexpr Layout Of() {
78 return Layout(sizeof(T), alignof(T));
79 }
80
82 template <typename T, std::enable_if_t<is_bounded_array_v<T>, int> = 0>
83 static constexpr Layout Of() {
84 return Layout(sizeof(T), alignof(std::remove_extent_t<T>));
85 }
86
88 template <typename T, std::enable_if_t<is_unbounded_array_v<T>, int> = 0>
89 static constexpr Layout Of(size_t count);
90
93 static constexpr Layout Unwrap(const Result<Layout>& result) {
94 return result.ok() ? (*result) : Layout();
95 }
96
98 constexpr Layout Extend(size_t size) const;
99
101 constexpr Layout Align(size_t alignment) const {
102 return Layout(size_, std::max(alignment, alignment_));
103 }
104
107 template <typename T>
108 constexpr Layout AlignTo() const {
109 return Align(alignof(T));
110 }
111
112 private:
113 size_t size_;
114 size_t alignment_;
115};
116
117inline bool operator==(const Layout& lhs, const Layout& rhs) {
118 return lhs.size() == rhs.size() && lhs.alignment() == rhs.alignment();
119}
120
121inline bool operator!=(const Layout& lhs, const Layout& rhs) {
122 return !(lhs == rhs);
123}
124
126
127// Template and inline method implementations.
128
129template <typename T, std::enable_if_t<is_unbounded_array_v<T>, int>>
130constexpr Layout Layout::Of(size_t count) {
131 using U = std::remove_extent_t<T>;
132 size_t size = sizeof(U);
133 Hardening::Multiply(size, count);
134 return Layout(size, alignof(U));
135}
136
137constexpr Layout Layout::Extend(size_t size) const {
138 Hardening::Increment(size, size_);
139 return Layout(size, alignment_);
140}
141
142} // namespace allocator
143} // namespace pw
Definition: result.h:145
constexpr bool ok() const
Definition: result.h:451
Definition: layout.h:64
static constexpr Layout Of()
Creates a Layout for the given type.
Definition: layout.h:77
constexpr Layout Extend(size_t size) const
Returns a new layout from this object increased by the given size.
Definition: layout.h:137
static constexpr Layout Unwrap(const Result< Layout > &result)
Definition: layout.h:93
constexpr Layout Align(size_t alignment) const
Returns a new layout from this object with at least the given alignment.
Definition: layout.h:101
constexpr Layout AlignTo() const
Definition: layout.h:108
The Pigweed namespace.
Definition: alignment.h:27
Definition: layout.h:37
Definition: layout.h:28