• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_assert/assert.h"
19 #include "pw_preprocessor/compiler.h"
20 #include "pw_result/result.h"
21 
22 namespace pw::allocator {
23 
24 /// Describes the layout of a block of memory.
25 ///
26 /// Layouts are passed to allocators, and consist of a (possibly padded) size
27 /// and a power-of-two alignment no larger than the size. Layouts can be
28 /// constructed for a type `T` using `Layout::Of`.
29 ///
30 /// Example:
31 ///
32 /// @code{.cpp}
33 ///    struct MyStruct {
34 ///      uint8_t field1[3];
35 ///      uint32_t field2[3];
36 ///    };
37 ///    constexpr Layout layout_for_struct = Layout::Of<MyStruct>();
38 /// @endcode
39 class Layout {
40  public:
41   constexpr Layout() = default;
42   constexpr Layout(size_t size, size_t alignment = alignof(std::max_align_t))
size_(size)43       : size_(size), alignment_(alignment) {}
44 
45   /// Creates a Layout for the given type.
46   template <typename T>
Of()47   static constexpr Layout Of() {
48     return Layout(sizeof(T), alignof(T));
49   }
50 
51   /// If the result is okay, returns its contained layout; otherwise, returns a
52   /// default layout.
Unwrap(const Result<Layout> & result)53   static constexpr Layout Unwrap(const Result<Layout>& result) {
54     return result.ok() ? (*result) : Layout();
55   }
56 
Extend(size_t size)57   constexpr Layout Extend(size_t size) const {
58     PW_ASSERT(!PW_ADD_OVERFLOW(size, size_, &size));
59     return Layout(size, alignment_);
60   }
61 
size()62   size_t size() const { return size_; }
alignment()63   size_t alignment() const { return alignment_; }
64 
65  private:
66   size_t size_ = 0;
67   size_t alignment_ = 1;
68 };
69 
70 inline bool operator==(const Layout& lhs, const Layout& rhs) {
71   return lhs.size() == rhs.size() && lhs.alignment() == rhs.alignment();
72 }
73 
74 inline bool operator!=(const Layout& lhs, const Layout& rhs) {
75   return !(lhs == rhs);
76 }
77 
78 }  // namespace pw::allocator
79