Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
cookie_guard.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 COOKIE_GUARD_H
96#define COOKIE_GUARD_H
97
98#include <vector>
99#include <utility>
100#include <tpl_graph.H>
101
102namespace Aleph {
103
118template <class GT>
120{
121public:
122 using Node = typename GT::Node;
123 using Arc = typename GT::Arc;
124
126 using Node_Deleter = std::function<void(Node*)>;
127
129 using Arc_Deleter = std::function<void(Arc*)>;
130
131private:
137 bool active;
138
139public:
146 Cookie_Guard(const GT & g, bool _clear_nodes = true, bool _clear_arcs = true) noexcept
148 node_deleter(nullptr), arc_deleter(nullptr), active(true)
149 {}
150
172
174 Cookie_Guard(const Cookie_Guard &) = delete;
176
179 : graph(other.graph), clear_nodes(other.clear_nodes),
180 clear_arcs(other.clear_arcs), node_deleter(std::move(other.node_deleter)),
181 arc_deleter(std::move(other.arc_deleter)), active(other.active)
182 {
183 other.active = false;
184 }
185
188 {
189 if (this != &other)
190 {
191 release();
192 clear_nodes = other.clear_nodes;
193 clear_arcs = other.clear_arcs;
194 node_deleter = std::move(other.node_deleter);
195 arc_deleter = std::move(other.arc_deleter);
196 active = other.active;
197 other.active = false;
198 }
199 return *this;
200 }
201
209 {
210 active = false;
211 }
212
218 {
219 if (not active)
220 return;
221
222 if (clear_nodes)
223 {
224 for (auto it = graph.get_node_it(); it.has_curr(); it.next_ne())
225 {
226 Node * p = it.get_curr();
227 if (node_deleter)
228 node_deleter(p);
229 NODE_COOKIE(p) = nullptr;
230 }
231 }
232
233 if (clear_arcs)
234 {
235 for (auto it = graph.get_arc_it(); it.has_curr(); it.next_ne())
236 {
237 Arc * a = it.get_curr();
238 if (arc_deleter)
239 arc_deleter(a);
240 ARC_COOKIE(a) = nullptr;
241 }
242 }
243
244 active = false;
245 }
246
249 {
250 clear_now();
251 }
252};
253
254
273template <class GT>
275{
276public:
277 using Node = typename GT::Node;
278 using Arc = typename GT::Arc;
279
281 using Node_Cleanup = std::function<void(Node*)>;
282
284 using Arc_Cleanup = std::function<void(Arc*)>;
285
286private:
288 std::vector<std::pair<Node*, void*>> saved_node_cookies;
289 std::vector<std::pair<Arc*, void*>> saved_arc_cookies;
294 bool active;
295
296public:
311
335
337 Cookie_Saver(const Cookie_Saver &) = delete;
339
342 : graph(other.graph),
343 saved_node_cookies(std::move(other.saved_node_cookies)),
344 saved_arc_cookies(std::move(other.saved_arc_cookies)),
345 save_nodes(other.save_nodes), save_arcs(other.save_arcs),
346 node_cleanup(std::move(other.node_cleanup)),
347 arc_cleanup(std::move(other.arc_cleanup)),
348 active(other.active)
349 {
350 other.active = false;
351 }
352
355 {
356 if (this != &other)
357 {
358 restore_now();
359 saved_node_cookies = std::move(other.saved_node_cookies);
360 saved_arc_cookies = std::move(other.saved_arc_cookies);
361 save_nodes = other.save_nodes;
362 save_arcs = other.save_arcs;
363 node_cleanup = std::move(other.node_cleanup);
364 arc_cleanup = std::move(other.arc_cleanup);
365 active = other.active;
366 other.active = false;
367 }
368 return *this;
369 }
370
377 {
378 active = false;
379 saved_node_cookies.clear();
380 saved_arc_cookies.clear();
381 }
382
388 {
389 if (not active)
390 return;
391
392 // First, cleanup current (temporary) cookies if cleanup function provided
393 if (node_cleanup)
394 {
395 for (auto it = graph.get_node_it(); it.has_curr(); it.next_ne())
396 node_cleanup(it.get_curr());
397 }
398
399 if (arc_cleanup)
400 {
401 for (auto it = graph.get_arc_it(); it.has_curr(); it.next_ne())
402 arc_cleanup(it.get_curr());
403 }
404
405 // Restore saved cookies
406 for (auto & [node, cookie] : saved_node_cookies)
407 NODE_COOKIE(node) = cookie;
408
409 for (auto & [arc, cookie] : saved_arc_cookies)
410 ARC_COOKIE(arc) = cookie;
411
412 active = false;
413 saved_node_cookies.clear();
414 saved_arc_cookies.clear();
415 }
416
421 [[nodiscard]] const std::vector<std::pair<Node*, void*>> &
426
431 [[nodiscard]] const std::vector<std::pair<Arc*, void*>> &
436
439 {
440 restore_now();
441 }
442
443private:
445 {
446 if (save_nodes)
447 {
449 for (auto it = graph.get_node_it(); it.has_curr(); it.next_ne())
450 {
451 Node * p = it.get_curr();
452 saved_node_cookies.emplace_back(p, NODE_COOKIE(p));
453 }
454 }
455
456 if (save_arcs)
457 {
459 for (auto it = graph.get_arc_it(); it.has_curr(); it.next_ne())
460 {
461 Arc * a = it.get_curr();
462 saved_arc_cookies.emplace_back(a, ARC_COOKIE(a));
463 }
464 }
465 }
466};
467
468
491template <class GT, class Func>
492auto with_clean_cookies(GT & g, Func && func) -> decltype(func())
493{
495 return std::forward<Func>(func)();
496}
497
498
523template <class GT, class Func>
524auto with_saved_cookies(GT & g, Func && func) -> decltype(func())
525{
527 return std::forward<Func>(func)();
528}
529
530
558template <class GT, class Cleanup>
560{
561 const GT & graph;
563 bool active;
564
565public:
571 Scope_Guard(const GT & g, Cleanup cleanup)
572 : graph(g), cleanup_fn(std::move(cleanup)), active(true)
573 {}
574
576 Scope_Guard(const Scope_Guard &) = delete;
577 Scope_Guard & operator=(const Scope_Guard &) = delete;
578
581 : graph(other.graph), cleanup_fn(std::move(other.cleanup_fn)),
582 active(other.active)
583 {
584 other.active = false;
585 }
586
589 {
590 if (active)
592 }
593
598 void release() noexcept { active = false; }
599
601 [[nodiscard]] bool is_active() const noexcept { return active; }
602
608 {
609 if (active)
610 {
612 active = false;
613 }
614 }
615};
616
618template <class GT, class Cleanup>
620
621
622} // end namespace Aleph
623
624#endif // COOKIE_GUARD_H
625
RAII guard that clears graph cookies on destruction.
Cookie_Guard(const GT &g, bool _clear_nodes=true, bool _clear_arcs=true) noexcept
Construct a cookie guard for the given graph.
typename GT::Arc Arc
void release() noexcept
Release the guard without clearing cookies.
Arc_Deleter arc_deleter
Cookie_Guard(const GT &g, Node_Deleter nd, Arc_Deleter ad=nullptr) noexcept
Construct with custom deleters for cookie data.
void clear_now()
Manually trigger cleanup now.
Cookie_Guard & operator=(Cookie_Guard &&other) noexcept
Move assignment transfers ownership.
Cookie_Guard(Cookie_Guard &&other) noexcept
Move construction transfers ownership.
typename GT::Node Node
std::function< void(Arc *)> Arc_Deleter
Signature for custom arc cookie deleter.
Cookie_Guard & operator=(const Cookie_Guard &)=delete
Cookie_Guard(const Cookie_Guard &)=delete
Copying disabled.
Node_Deleter node_deleter
~Cookie_Guard()
Destructor - clears cookies if guard is still active.
std::function< void(Node *)> Node_Deleter
Signature for custom node cookie deleter.
RAII guard that saves and restores graph cookies.
typename GT::Node Node
const std::vector< std::pair< Node *, void * > > & get_saved_node_cookies() const noexcept
Get access to saved node cookies.
std::function< void(Arc *)> Arc_Cleanup
Signature for custom cleanup of temporary arc cookies.
std::vector< std::pair< Arc *, void * > > saved_arc_cookies
Cookie_Saver(const Cookie_Saver &)=delete
Copying disabled.
const std::vector< std::pair< Arc *, void * > > & get_saved_arc_cookies() const noexcept
Get access to saved arc cookies.
std::function< void(Node *)> Node_Cleanup
Signature for custom cleanup of temporary node cookies.
std::vector< std::pair< Node *, void * > > saved_node_cookies
Node_Cleanup node_cleanup
Cookie_Saver(const GT &g, bool _save_nodes=true, bool _save_arcs=true)
Construct a cookie saver for the given graph.
void discard() noexcept
Discard saved cookies without restoring.
typename GT::Arc Arc
Cookie_Saver(Cookie_Saver &&other) noexcept
Move construction transfers ownership.
Cookie_Saver & operator=(Cookie_Saver &&other) noexcept
Move assignment transfers ownership.
Cookie_Saver(const GT &g, Node_Cleanup nc, Arc_Cleanup ac=nullptr)
Construct with custom cleanup for temporary cookies.
Cookie_Saver & operator=(const Cookie_Saver &)=delete
Arc_Cleanup arc_cleanup
~Cookie_Saver()
Destructor - restores cookies if saver is still active.
void restore_now()
Manually restore cookies now.
Graph_Arc< int > Arc
The node class type.
Definition tpl_graph.H:433
Generic RAII scope guard for cleanup operations on graphs.
Scope_Guard(const GT &g, Cleanup cleanup)
Construct a scope guard.
Scope_Guard(Scope_Guard &&other) noexcept
Move construction transfers ownership.
Scope_Guard & operator=(const Scope_Guard &)=delete
void release() noexcept
Release the guard without calling cleanup.
Scope_Guard(const Scope_Guard &)=delete
Copying disabled.
bool is_active() const noexcept
Check if guard is still active.
void cleanup_now()
Execute cleanup immediately and deactivate.
~Scope_Guard()
Destructor - calls cleanup function if still active.
auto get_arc_it() const noexcept
Obtains an iterator to the arc of graph.
Definition graph-dry.H:2802
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
constexpr size_t get_num_arcs() const noexcept
Definition graph-dry.H:778
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
Definition graph-dry.H:2780
#define ARC_COOKIE(p)
Return the arc cookie
auto with_clean_cookies(GT &g, Func &&func) -> decltype(func())
Convenience function to run an algorithm with automatic cookie cleanup.
auto with_saved_cookies(GT &g, Func &&func) -> decltype(func())
Convenience function to run an algorithm preserving existing cookies.
#define NODE_COOKIE(p)
Return the node cookie
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Generic graph and digraph implementations.