Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
driven_table.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
95# ifndef DRIVEN_TABLE_H
96# define DRIVEN_TABLE_H
97
98# include <aleph.H>
99# include <tpl_dynArray.H>
100# include <ah-errors.H>
101# include <functional>
102# include <memory>
103# include <type_traits>
104
112typedef void * (*Event_Fct)(void *);
113
135template <typename Signature>
137{
138public:
139 using Event_Handler = std::function<Signature>;
140
141protected:
142 [[nodiscard]] virtual const Event_Handler* read_table(size_t i) const = 0;
143
144 virtual void write_table(size_t i, Event_Handler&& event_fct) = 0;
145
146 virtual void clear_slot(size_t i) = 0;
147
148public:
152 [[nodiscard]] virtual size_t size() const = 0;
153
155 virtual ~Event_Table() = default;
156
157private:
162 {
163 write_table(size(), std::move(fct));
164 }
165
166public:
176 template <typename Callable>
177 void register_event(const size_t index, Callable&& fct)
178 {
179 ah_range_error_if(index >= size()) << "Index out of range";
180 ah_range_error_if(read_table(index) != nullptr) << "Index is already used";
181
182 write_table(index, Event_Handler(std::forward<Callable>(fct)));
183 }
184
193 template <typename Callable>
195 {
196 append_event_to_table(Event_Handler(std::forward<Callable>(fct)));
197 return size() - 1;
198 }
199
207 void unregister_event(const size_t index)
208 {
209 ah_range_error_if(index >= size()) << "Index out of range";
210 ah_range_error_if(read_table(index) == nullptr) << "Index is not used";
211
212 clear_slot(index);
213 }
214
220 bool is_registered(const size_t index) const
221 {
222 return index < size() and read_table(index) != nullptr;
223 }
224
232 template <typename F>
233 bool check(const size_t, F) const
234 {
235 return false;
236 }
237
248 template <typename... Args>
249 auto execute_event(const size_t index, Args&&... args) const
250 {
251 ah_range_error_if(index >= size())
252 << "index " << index << " out of range [0, " << size() << ')';
253
254 const auto* event_fct = read_table(index);
255
256 ah_range_error_if(event_fct == nullptr) << "Index is not used";
257
258 return (*event_fct)(std::forward<Args>(args)...);
259 }
260};
261
262
267template <>
268class Event_Table<void*(void*)>
269{
270public:
271 using Event_Handler = std::function<void*(void*)>;
272
273protected:
274 [[nodiscard]] virtual const Event_Handler* read_table(size_t i) const = 0;
275
276 virtual void write_table(size_t i, Event_Handler&& event_fct) = 0;
277
278 virtual void clear_slot(size_t i) = 0;
279
280public:
281 [[nodiscard]] virtual size_t size() const = 0;
282
283 virtual ~Event_Table() = default;
284
285private:
287 {
288 write_table(size(), std::move(fct));
289 }
290
291public:
292 template <typename Callable>
293 void register_event(const size_t index, Callable&& fct)
294 {
295 ah_range_error_if(index >= size()) << "Index out of range";
296 ah_range_error_if(read_table(index) != nullptr) << "Index is already used";
297
298 write_table(index, Event_Handler(std::forward<Callable>(fct)));
299 }
300
301 template <typename Callable>
303 {
304 append_event_to_table(Event_Handler(std::forward<Callable>(fct)));
305 return size() - 1;
306 }
307
308 void unregister_event(const size_t index)
309 {
310 ah_range_error_if(index >= size()) << "Index out of range";
311 ah_range_error_if(read_table(index) == nullptr) << "Index is not used";
312
313 clear_slot(index);
314 }
315
316 bool is_registered(const size_t index) const
317 {
318 return index < size() and read_table(index) != nullptr;
319 }
320
321 // Legacy check for void* function pointers - compares function addresses
322 bool check(const size_t index, void* (*fct)(void*)) const
323 {
324 if (index >= size() || !is_registered(index))
325 return false;
326
327 const auto* handler = read_table(index);
328 if (!handler)
329 return false;
330
331 // Get the target function pointer from std::function
332 auto target = handler->template target<void* (*)(void*)>();
333 return target && *target == fct;
334 }
335
336 // Special override for void*(void*) with default nullptr argument
337 void* execute_event(const size_t index, void* input = nullptr) const
338 {
339 ah_range_error_if(index >= size())
340 << "index " << index << " out of range [0, " << size() << ')';
341
342 const auto* event_fct = read_table(index);
343
344 ah_range_error_if(event_fct == nullptr) << "Index is not used";
345
346 return (*event_fct)(input);
347 }
348};
349
350
377template <typename Signature>
378class Static_Event_Table : public Event_Table<Signature>
379{
380public:
382
383private:
384 std::unique_ptr<Event_Handler[]> table;
385 size_t size_table;
386
391 void verify_index(const size_t i) const
392 {
393 ah_range_error_if(i >= size_table) << "index out of range";
394 }
395
397 [[nodiscard]] const Event_Handler* read_table(const size_t i) const override
398 {
399 verify_index(i);
400 return table[i] ? &table[i] : nullptr;
401 }
402
404 void write_table(const size_t i, Event_Handler&& event_fct) override
405 {
406 verify_index(i);
407 table[i] = std::move(event_fct);
408 }
409
411 void clear_slot(size_t i) override
412 {
413 verify_index(i);
414 table[i] = Event_Handler();
415 }
416
417public:
419 [[nodiscard]] size_t size() const override { return size_table; }
420
427 explicit Static_Event_Table(const size_t num_events = 0)
430 {
431 }
432
435
437
445 : table(std::move(other.table)), size_table(other.size_table)
446 {
447 other.size_table = 0;
448 }
449
458 {
459 if (this != &other)
460 {
461 table = std::move(other.table);
462 size_table = other.size_table;
463 other.size_table = 0;
464 }
465 return *this;
466 }
467
469 ~Static_Event_Table() override = default;
470};
471
472
513template <typename Signature>
514class Dynamic_Event_Table : public Event_Table<Signature>
515{
516public:
518
519private:
521
523 [[nodiscard]] const Event_Handler* read_table(const size_t i) const override
524 {
525 const Event_Handler& handler = table[i];
526 return handler ? &handler : nullptr;
527 }
528
530 void write_table(const size_t i, Event_Handler&& event_fct) override
531 {
532 table[i] = std::move(event_fct);
533 }
534
536 void clear_slot(size_t i) override
537 {
538 table[i] = Event_Handler();
539 }
540
541public:
543 [[nodiscard]] size_t size() const override { return table.size(); }
544
552 explicit Dynamic_Event_Table(const size_t num_events = 0) : table(num_events)
553 {
554 // Initialize all slots with empty handlers to avoid DynArray access exceptions
555 for (size_t i = 0; i < num_events; ++i)
556 table[i] = Event_Handler();
557 }
558
561
563
566
569
572};
573
574
575// =============================================================================
576// Legacy Type Aliases for Backward Compatibility
577// =============================================================================
578
587
596
597
598# endif
Exception handling system with formatted messages for Aleph-w.
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
Definition ah-errors.H:207
Core header for the Aleph-w library.
size_t size() const noexcept
Return the current dimension of array.
Dynamic (growable) event table implementation.
size_t size() const override
Get the current table size (implements Event_Table virtual method)
typename Event_Table< Signature >::Event_Handler Event_Handler
const Event_Handler * read_table(const size_t i) const override
Read event at index (implements Event_Table virtual method)
Dynamic_Event_Table & operator=(const Dynamic_Event_Table &)=delete
Dynamic_Event_Table(Dynamic_Event_Table &&) noexcept=default
Move constructor.
Dynamic_Event_Table(const Dynamic_Event_Table &)=delete
Copying disabled (events may contain non-copyable captures)
Dynamic_Event_Table(const size_t num_events=0)
Construct a dynamic event table.
DynArray< Event_Handler > table
Dynamic array of event handlers.
void clear_slot(size_t i) override
Clear event at index (implements Event_Table virtual method)
void write_table(const size_t i, Event_Handler &&event_fct) override
Write event at index (implements Event_Table virtual method)
void append_event_to_table(Event_Handler &&fct)
void register_event(const size_t index, Callable &&fct)
virtual ~Event_Table()=default
bool check(const size_t index, void *(*fct)(void *)) const
std::function< void *(void *)> Event_Handler
size_t register_event(Callable &&fct)
virtual size_t size() const =0
void unregister_event(const size_t index)
virtual const Event_Handler * read_table(size_t i) const =0
virtual void write_table(size_t i, Event_Handler &&event_fct)=0
virtual void clear_slot(size_t i)=0
void * execute_event(const size_t index, void *input=nullptr) const
bool is_registered(const size_t index) const
Abstract base class for type-safe event tables.
virtual void write_table(size_t i, Event_Handler &&event_fct)=0
virtual size_t size() const =0
Get the number of event slots in the table.
void append_event_to_table(Event_Handler &&fct)
Append an event to the end of the table (internal use).
bool is_registered(const size_t index) const
Check if an event is registered at the given index.
virtual ~Event_Table()=default
Virtual destructor for proper cleanup in derived classes.
void register_event(const size_t index, Callable &&fct)
Register an event at a specific index.
std::function< Signature > Event_Handler
virtual void clear_slot(size_t i)=0
size_t register_event(Callable &&fct)
Append a new event and return its auto-assigned index.
void unregister_event(const size_t index)
Unregister an event at the given index.
bool check(const size_t, F) const
Legacy check method (for backward compatibility).
virtual const Event_Handler * read_table(size_t i) const =0
auto execute_event(const size_t index, Args &&... args) const
Execute the event at the given index with type-safe arguments.
Fixed-size event table implementation.
void write_table(const size_t i, Event_Handler &&event_fct) override
Write event at index (implements Event_Table virtual method)
void clear_slot(size_t i) override
Clear event at index (implements Event_Table virtual method)
Static_Event_Table(const size_t num_events=0)
Construct a static event table with a fixed size.
~Static_Event_Table() override=default
Destructor - automatically frees the underlying array.
Static_Event_Table(const Static_Event_Table &)=delete
Copying disabled (events may contain non-copyable captures)
Static_Event_Table & operator=(const Static_Event_Table &)=delete
Static_Event_Table & operator=(Static_Event_Table &&other) noexcept
Move assignment - transfers ownership of the array.
size_t size_table
Fixed size of the table.
typename Event_Table< Signature >::Event_Handler Event_Handler
std::unique_ptr< Event_Handler[]> table
Array of event handlers.
const Event_Handler * read_table(const size_t i) const override
Read event at index (implements Event_Table virtual method)
Static_Event_Table(Static_Event_Table &&other) noexcept
Move constructor - transfers ownership of the array.
void verify_index(const size_t i) const
Verify index is within valid range.
size_t size() const override
Get table size (implements Event_Table virtual method)
size_t size(Node *root) noexcept
DynList< T > maps(const C &c, Op op)
Classic map operation.
Lazy and scalable dynamic array implementation.