POSIX Shared Memory Data Structures 1.0
High-performance lock-free data structures for inter-process communication
Loading...
Searching...
No Matches
shm_array.h
Go to the documentation of this file.
1
9#pragma once
10#include "posix_shm.h"
11#include "shm_span.h"
12#include "shm_table.h"
13#include <stdexcept>
14#include <algorithm>
15#include <concepts>
16#include <span>
17#include <string_view>
18#include <iterator>
19
60template <typename T, typename TableType = shm_table>
61 requires std::is_trivially_copyable_v<T>
62class shm_array : public shm_span<T, posix_shm_impl<TableType>>
63{
64private:
65 const typename TableType::entry* _table_entry{nullptr};
66
67public:
96 template<typename ShmType>
97 shm_array(ShmType &shared_mem, std::string_view name, size_t count = 0)
98 : shm_span<T, posix_shm_impl<TableType>>(shared_mem, 0, 0)
99 {
100 static_assert(std::is_same_v<typename ShmType::table_type, TableType>,
101 "SharedMemory table type must match array table type");
102 initialize(name, count);
103 }
104
114 void initialize(std::string_view name, size_t count = 0)
115 {
116 auto *table = static_cast<TableType *>(this->shm.get_base_addr());
117
118 // Convert string_view to null-terminated string for find
119 char name_buf[TableType::MAX_NAME_SIZE]{};
120 size_t copy_len = std::min(name.size(), sizeof(name_buf) - 1);
121 std::copy_n(name.begin(), copy_len, name_buf);
122
123 auto *entry = table->find(name_buf);
124
125 if (entry)
126 {
127 // Open existing array
128 if (count != 0 && entry->num_elem != count)
129 {
130 throw std::runtime_error("Mismatch in array size");
131 }
132 this->offset = entry->offset; // Keep as byte offset
133 this->num_elem = entry->num_elem;
134 _table_entry = entry;
135 }
136 else if (count > 0)
137 {
138 // Create new array
139 size_t required_size = count * sizeof(T);
140 size_t current_used = table->get_total_allocated_size();
141 // get_total_size() already excludes the header (which includes the table)
142 size_t available_size = this->shm.get_total_size() - current_used;
143
144 if (required_size > available_size)
145 {
146 throw std::runtime_error("Not enough space in shared memory");
147 }
148
149 // Data must come after the table
150 size_t byte_offset = sizeof(TableType) + current_used;
151 this->offset = byte_offset; // Keep as byte offset
152 this->num_elem = count;
153
154 if (!table->add(name_buf, byte_offset, required_size, sizeof(T), count))
155 {
156 throw std::runtime_error("Failed to add array to table");
157 }
158 // Find the entry we just added to get a pointer to it
159 _table_entry = table->find(name_buf);
160 }
161 else
162 {
163 throw std::runtime_error("Array not found and size not specified");
164 }
165 }
166
179 [[nodiscard]] T &at(size_t pos)
180 {
181 if (pos >= this->num_elem)
182 {
183 throw std::out_of_range("Array index out of range");
184 }
185 return (*this)[pos];
186 }
187
190 [[nodiscard]] const T &at(size_t pos) const
191 {
192 if (pos >= this->num_elem)
193 {
194 throw std::out_of_range("Array index out of range");
195 }
196 return (*this)[pos];
197 }
198
202 [[nodiscard]] T &front() { return *this->data(); }
203
205 [[nodiscard]] const T &front() const { return *this->data(); }
206
210 [[nodiscard]] T &back() { return *(this->data() + this->num_elem - 1); }
211
213 [[nodiscard]] const T &back() const { return *(this->data() + this->num_elem - 1); }
214
217 [[nodiscard]] bool empty() const noexcept { return this->num_elem == 0; }
218
221 [[nodiscard]] size_t size() const noexcept { return this->num_elem; }
222
238 void fill(const T &value)
239 {
240 std::fill_n(this->data(), this->num_elem, value);
241 }
242
256 [[nodiscard]] std::span<T> as_span() noexcept
257 {
258 return std::span<T>(this->data(), this->num_elem);
259 }
260
262 [[nodiscard]] std::span<const T> as_span() const noexcept
263 {
264 return std::span<const T>(this->data(), this->num_elem);
265 }
266
269 using value_type = T;
270 using size_type = size_t;
271 using difference_type = std::ptrdiff_t;
272 using reference = T&;
273 using const_reference = const T&;
274 using pointer = T*;
275 using const_pointer = const T*;
276 using iterator = T*;
277 using const_iterator = const T*;
278 using reverse_iterator = std::reverse_iterator<iterator>;
279 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
281
284
286 [[nodiscard]] iterator begin() noexcept { return this->data(); }
287
289 [[nodiscard]] iterator end() noexcept { return this->data() + this->num_elem; }
290
293
295 [[nodiscard]] const_iterator end() const noexcept { return this->data() + this->num_elem; }
296
299
303
306
309
312
315
318
321
325
329
334
337
353 [[nodiscard]] std::string_view name() const noexcept {
354 return _table_entry ? std::string_view(_table_entry->name.data()) : std::string_view{};
355 }
356};
POSIX shared memory wrapper with RAII and reference counting.
Definition posix_shm.h:62
Fixed-size array in shared memory with zero-overhead access.
Definition shm_array.h:63
const T & back() const
Access last element (const)
Definition shm_array.h:213
const T & at(size_t pos) const
Const version of at()
Definition shm_array.h:190
T & at(size_t pos)
Bounds-checked element access.
Definition shm_array.h:179
const T & front() const
Access first element (const)
Definition shm_array.h:205
std::string_view name() const noexcept
Get array name from metadata table.
Definition shm_array.h:353
const_reverse_iterator crbegin() const noexcept
Get const reverse iterator to beginning (explicit)
Definition shm_array.h:320
T & reference
Reference type.
Definition shm_array.h:272
std::span< const T > as_span() const noexcept
Convert to const span.
Definition shm_array.h:262
T value_type
Element type.
Definition shm_array.h:269
const_pointer data() const noexcept
Get const pointer to underlying data.
Definition shm_array.h:336
void fill(const T &value)
Fill array with value.
Definition shm_array.h:238
const T * const_iterator
Const iterator.
Definition shm_array.h:277
size_type max_size() const noexcept
Get maximum size (same as size() for fixed arrays)
Definition shm_array.h:328
const_iterator cend() const noexcept
Get const iterator to end (explicit)
Definition shm_array.h:301
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator.
Definition shm_array.h:278
shm_array(ShmType &shared_mem, std::string_view name, size_t count=0)
Create new array or attach to existing array by name.
Definition shm_array.h:97
const_reverse_iterator crend() const noexcept
Get const reverse iterator to end (explicit)
Definition shm_array.h:323
size_t size_type
Size type.
Definition shm_array.h:270
const T * const_pointer
Const pointer.
Definition shm_array.h:275
const_iterator begin() const noexcept
Get const iterator to beginning.
Definition shm_array.h:292
std::ptrdiff_t difference_type
Iterator difference.
Definition shm_array.h:271
const_reverse_iterator rbegin() const noexcept
Get const reverse iterator to beginning.
Definition shm_array.h:314
void initialize(std::string_view name, size_t count=0)
Internal initialization helper.
Definition shm_array.h:114
T & back()
Access last element.
Definition shm_array.h:210
const T & const_reference
Const reference.
Definition shm_array.h:273
std::span< T > as_span() noexcept
Convert to std::span for modern C++ usage.
Definition shm_array.h:256
T * pointer
Pointer type.
Definition shm_array.h:274
const_iterator cbegin() const noexcept
Get const iterator to beginning (explicit)
Definition shm_array.h:298
reverse_iterator rbegin() noexcept
Get reverse iterator to beginning.
Definition shm_array.h:308
const_iterator end() const noexcept
Get const iterator to end.
Definition shm_array.h:295
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse.
Definition shm_array.h:279
iterator begin() noexcept
Get iterator to beginning.
Definition shm_array.h:286
const_reverse_iterator rend() const noexcept
Get const reverse iterator to end.
Definition shm_array.h:317
bool empty() const noexcept
Check if array is empty.
Definition shm_array.h:217
T & front()
Access first element.
Definition shm_array.h:202
iterator end() noexcept
Get iterator to end.
Definition shm_array.h:289
reverse_iterator rend() noexcept
Get reverse iterator to end.
Definition shm_array.h:311
T * iterator
Iterator type (raw pointer)
Definition shm_array.h:276
size_t size() const noexcept
Get number of elements.
Definition shm_array.h:221
pointer data() noexcept
Get pointer to underlying data.
Definition shm_array.h:333
Base class for shared memory data structures that span a region.
Definition shm_span.h:11
ShmType & shm
Definition shm_span.h:13
size_t offset
Definition shm_span.h:14
size_t num_elem
Definition shm_span.h:15
Core POSIX shared memory management with automatic reference counting.