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
113using Event_Fct [[deprecated("Use the templated Event_Table with std::function handlers instead")]]
114 = void *(*)(void *);
115
137template <typename Signature>
139{
140public:
141 using Event_Handler = std::function<Signature>;
142
143protected:
144 [[nodiscard]] virtual const Event_Handler* read_table(size_t i) const = 0;
145
146 virtual void write_table(size_t i, Event_Handler&& event_fct) = 0;
147
148 virtual void clear_slot(size_t i) = 0;
149
150public:
154 [[nodiscard]] virtual size_t size() const = 0;
155
157 virtual ~Event_Table() = default;
158
159private:
164 {
165 write_table(size(), std::move(fct));
166 }
167
168public:
178 template <typename Callable>
179 void register_event(const size_t index, Callable&& fct)
180 {
181 ah_range_error_if(index >= size()) << "Index out of range";
182 ah_range_error_if(read_table(index) != nullptr) << "Index is already used";
183
184 write_table(index, Event_Handler(std::forward<Callable>(fct)));
185 }
186
195 template <typename Callable>
197 {
198 append_event_to_table(Event_Handler(std::forward<Callable>(fct)));
199 return size() - 1;
200 }
201
209 void unregister_event(const size_t index)
210 {
211 ah_range_error_if(index >= size()) << "Index out of range";
212 ah_range_error_if(read_table(index) == nullptr) << "Index is not used";
213
214 clear_slot(index);
215 }
216
222 bool is_registered(const size_t index) const
223 {
224 return index < size() and read_table(index) != nullptr;
225 }
226
234 template <typename F>
235 bool check(const size_t, F) const
236 {
237 return false;
238 }
239
250 template <typename... Args>
251 auto execute_event(const size_t index, Args&&... args) const
252 {
253 ah_range_error_if(index >= size())
254 << "index " << index << " out of range [0, " << size() << ')';
255
256 const auto* event_fct = read_table(index);
257
258 ah_range_error_if(event_fct == nullptr) << "Index is not used";
259
260 return (*event_fct)(std::forward<Args>(args)...);
261 }
262};
263
264
269template <>
270class Event_Table<void*(void*)>
271{
272public:
273 using Event_Handler = std::function<void*(void*)>;
274
275protected:
276 [[nodiscard]] virtual const Event_Handler* read_table(size_t i) const = 0;
277
278 virtual void write_table(size_t i, Event_Handler&& event_fct) = 0;
279
280 virtual void clear_slot(size_t i) = 0;
281
282public:
283 [[nodiscard]] virtual size_t size() const = 0;
284
285 virtual ~Event_Table() = default;
286
287private:
289 {
290 write_table(size(), std::move(fct));
291 }
292
293public:
294 template <typename Callable>
295 void register_event(const size_t index, Callable&& fct)
296 {
297 ah_range_error_if(index >= size()) << "Index out of range";
298 ah_range_error_if(read_table(index) != nullptr) << "Index is already used";
299
300 write_table(index, Event_Handler(std::forward<Callable>(fct)));
301 }
302
303 template <typename Callable>
305 {
306 append_event_to_table(Event_Handler(std::forward<Callable>(fct)));
307 return size() - 1;
308 }
309
310 void unregister_event(const size_t index)
311 {
312 ah_range_error_if(index >= size()) << "Index out of range";
313 ah_range_error_if(read_table(index) == nullptr) << "Index is not used";
314
315 clear_slot(index);
316 }
317
318 bool is_registered(const size_t index) const
319 {
320 return index < size() and read_table(index) != nullptr;
321 }
322
323 // Legacy check for void* function pointers - compares function addresses
324 bool check(const size_t index, void* (*fct)(void*)) const
325 {
326 if (index >= size() || !is_registered(index))
327 return false;
328
329 const auto* handler = read_table(index);
330 if (!handler)
331 return false;
332
333 // Get the target function pointer from std::function
334 auto target = handler->template target<void* (*)(void*)>();
335 return target && *target == fct;
336 }
337
338 // Special override for void*(void*) with default nullptr argument
339 void* execute_event(const size_t index, void* input = nullptr) const
340 {
341 ah_range_error_if(index >= size())
342 << "index " << index << " out of range [0, " << size() << ')';
343
344 const auto* event_fct = read_table(index);
345
346 ah_range_error_if(event_fct == nullptr) << "Index is not used";
347
348 return (*event_fct)(input);
349 }
350};
351
352
379template <typename Signature>
380class Static_Event_Table : public Event_Table<Signature>
381{
382public:
384
385private:
386 std::unique_ptr<Event_Handler[]> table;
387 size_t size_table;
388
393 void verify_index(const size_t i) const
394 {
395 ah_range_error_if(i >= size_table) << "index out of range";
396 }
397
399 [[nodiscard]] const Event_Handler* read_table(const size_t i) const override
400 {
401 verify_index(i);
402 return table[i] ? &table[i] : nullptr;
403 }
404
406 void write_table(const size_t i, Event_Handler&& event_fct) override
407 {
408 verify_index(i);
409 table[i] = std::move(event_fct);
410 }
411
413 void clear_slot(size_t i) override
414 {
415 verify_index(i);
416 table[i] = Event_Handler();
417 }
418
419public:
421 [[nodiscard]] size_t size() const override { return size_table; }
422
429 explicit Static_Event_Table(const size_t num_events = 0)
430 : table(num_events > 0 ? new Event_Handler[num_events] : nullptr),
432 {
433 }
434
437
439
447 : table(std::move(other.table)), size_table(other.size_table)
448 {
449 other.size_table = 0;
450 }
451
460 {
461 if (this != &other)
462 {
463 table = std::move(other.table);
464 size_table = other.size_table;
465 other.size_table = 0;
466 }
467 return *this;
468 }
469
471 ~Static_Event_Table() override = default;
472};
473
474
515template <typename Signature>
516class Dynamic_Event_Table : public Event_Table<Signature>
517{
518public:
520
521private:
523
525 [[nodiscard]] const Event_Handler* read_table(const size_t i) const override
526 {
527 const Event_Handler& handler = table[i];
528 return handler ? &handler : nullptr;
529 }
530
532 void write_table(const size_t i, Event_Handler&& event_fct) override
533 {
534 table[i] = std::move(event_fct);
535 }
536
538 void clear_slot(size_t i) override
539 {
540 table[i] = Event_Handler();
541 }
542
543public:
545 [[nodiscard]] size_t size() const override { return table.size(); }
546
554 explicit Dynamic_Event_Table(const size_t num_events = 0) : table(num_events)
555 {
556 // Initialize all slots with empty handlers to avoid DynArray access exceptions
557 for (size_t i = 0; i < num_events; ++i)
558 table[i] = Event_Handler();
559 }
560
563
565
568
571
574};
575
576
577// =============================================================================
578// Legacy Type Aliases for Backward Compatibility
579// =============================================================================
580
590 [[deprecated("Use Static_Event_Table<Signature> with a typed signature instead")]]
591 = Static_Event_Table<void*(void*)>;
592
602 [[deprecated("Use Dynamic_Event_Table<Signature> with a typed signature instead")]]
603 = Dynamic_Event_Table<void*(void*)>;
604
605
606# 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:212
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)
void *(*)(void *) Event_Fct
Type alias for legacy event handler functions.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
size_t size(Node *root) noexcept
and
Check uniqueness with explicit hash + equality functors.
Lazy and scalable dynamic array implementation.