emlabcpp
modern opinionated embedded C++ library
stack_resource.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./memory_resource.h"
27 #include "./util.h"
28 
29 #include <array>
30 #include <cstring>
31 
32 namespace emlabcpp::pmr
33 {
34 
35 template < std::size_t Capacity >
37 {
38  struct node
39  {
40  std::byte* prev_ptr;
41  std::byte* next_ptr;
42  };
43 
44  static constexpr std::size_t node_size = sizeof( node );
45  using buffer = std::array< std::byte, Capacity >;
46 
47 public:
49  {
50  top_ = buff_.data() + node_size;
51  set_node( top_, nullptr, nullptr );
52  }
53 
54  stack_resource( stack_resource const& ) = delete;
58 
59  [[nodiscard]] void*
60  allocate( std::size_t const bytes, std::size_t const alignment ) override
61  {
62 
63  std::byte* prev_ptr = top_;
64  node const prev_node = get_node( prev_ptr );
65 
66  auto* const p = reinterpret_cast< std::byte* >( align( top_, alignment ) );
67 
68  std::byte* new_top = p + bytes + node_size;
69 
70  if ( new_top + node_size > buff_.end() )
71  return nullptr;
72 
73  top_ = new_top;
74 
75  set_node( top_, prev_ptr, nullptr );
76  set_node( prev_ptr, prev_node.prev_ptr, top_ );
77 
78  return p;
79  }
80 
81  [[nodiscard]] result
82  deallocate( void* const ptr, std::size_t const bytes, std::size_t const ) override
83  {
84  std::byte* node_ptr = reinterpret_cast< std::byte* >( ptr ) + bytes + node_size;
85  auto [prev_ptr, next_ptr] = get_node( node_ptr );
86 
87  auto [prev_prev_ptr, prev_next_ptr] = get_node( prev_ptr );
88  set_node( prev_ptr, prev_prev_ptr, next_ptr );
89 
90  if ( next_ptr == nullptr ) {
91  top_ = prev_ptr;
92  } else {
93  auto [next_prev_ptr, next_next_ptr] = get_node( next_ptr );
94  set_node( next_ptr, prev_ptr, next_next_ptr );
95  }
96 
97  return result::SUCCESS;
98  }
99 
100  [[nodiscard]] bool is_equal( pmr::memory_resource const& other ) const noexcept override
101  {
102  return this == &other;
103  }
104 
105  [[nodiscard]] bool is_full() const noexcept override
106  {
107  return top_ == buff_.end();
108  }
109 
110  ~stack_resource() override = default;
111 
112 private:
113  node get_node( std::byte* ptr )
114  {
115  ptr -= sizeof( std::byte* );
116 
117  std::byte* prev = nullptr;
118  std::memcpy( static_cast< void* >( &prev ), ptr, sizeof( std::byte* ) );
119 
120  ptr -= sizeof( std::byte* );
121 
122  std::byte* next = nullptr;
123  std::memcpy( static_cast< void* >( &next ), ptr, sizeof( std::byte* ) );
124  return { prev, next };
125  };
126 
127  void set_node( std::byte* ptr, std::byte* const prev, std::byte* const next ) const
128  {
129  ptr -= sizeof( std::byte* );
130  std::memcpy( ptr, static_cast< void const* >( &prev ), sizeof( std::byte* ) );
131  ptr -= sizeof( std::byte* );
132  std::memcpy( ptr, static_cast< void const* >( &next ), sizeof( std::byte* ) );
133  }
134 
135  std::byte* top_ = nullptr;
136  buffer buff_{};
137 };
138 
139 } // namespace emlabcpp::pmr
Definition: memory_resource.h:33
Definition: stack_resource.h:37
bool is_full() const noexcept override
Definition: stack_resource.h:105
stack_resource & operator=(stack_resource const &)=delete
stack_resource(stack_resource const &)=delete
stack_resource()
Definition: stack_resource.h:48
stack_resource & operator=(stack_resource &&)=delete
void * allocate(std::size_t const bytes, std::size_t const alignment) override
Definition: stack_resource.h:60
bool is_equal(pmr::memory_resource const &other) const noexcept override
Definition: stack_resource.h:100
~stack_resource() override=default
result deallocate(void *const ptr, std::size_t const bytes, std::size_t const) override
Definition: stack_resource.h:82
stack_resource(stack_resource &&)=delete
hdr_state next(hdr_state cs) noexcept
Definition: page.h:43
MIT License.
Definition: aliases.h:36
void * align(void *const ptr, std::size_t const alignment)
TODO: this needs tests.
Definition: util.h:41
constexpr std::array< std::byte, N > bytes(Args const &... args)
Conveft the provided arguments into array of std::byte.
Definition: algorithm.h:524
physical_quantity< 0, 0, 0, 0, 0, 0, 0, 0, 1 > byte
Definition: physical_quantity.h:118
result represents an result of some operation, as an alternative to returning just bool with true/fal...
Definition: result.h:42