22#ifndef LIBSEMIGROUPS_DETAIL_NODE_MANAGER_HPP_
23#define LIBSEMIGROUPS_DETAIL_NODE_MANAGER_HPP_
31#include "libsemigroups/config.hpp"
32#include "libsemigroups/constants.hpp"
33#include "libsemigroups/debug.hpp"
34#include "libsemigroups/exception.hpp"
35#include "libsemigroups/ranges.hpp"
39 template <
typename NodeType>
47 using node_type = NodeType;
48 using Perm = std::vector<node_type>;
56 NodeManager(NodeManager
const&) =
default;
57 NodeManager(NodeManager&&) =
default;
59 NodeManager& operator=(NodeManager
const&) =
default;
60 NodeManager& operator=(NodeManager&&) =
default;
72 node_type& lookahead_cursor() {
89 inline size_t node_capacity() const noexcept {
105 inline node_type first_free_node() const noexcept {
106 return _first_free_node;
121 inline bool has_free_nodes() const noexcept {
137 inline bool is_active_node(node_type c)
const {
138 LIBSEMIGROUPS_ASSERT(c < _ident.size() || c ==
UNDEFINED);
153 inline bool is_valid_node(node_type c)
const noexcept {
154 return c < _forwd.size();
169 inline node_type next_active_node(node_type c)
const {
170 LIBSEMIGROUPS_ASSERT(is_active_node(c));
176 auto cbegin_active_nodes()
const {
177 return rx::begin(ActiveNodesRange(
this));
182 auto cend_active_nodes()
const {
183 return rx::end(ActiveNodesRange(
this));
198 inline size_t number_of_nodes_active() const noexcept {
214 inline size_t number_of_nodes_defined() const noexcept {
230 inline size_t number_of_nodes_killed() const noexcept {
231 return _nodes_killed;
249 NodeManager& growth_factor(
float val);
260 float growth_factor() const noexcept {
261 return _growth_factor;
271 inline void union_nodes(node_type min, node_type max) {
272 LIBSEMIGROUPS_ASSERT(is_active_node(min));
273 LIBSEMIGROUPS_ASSERT(is_active_node(max));
274 LIBSEMIGROUPS_ASSERT(max > min);
283 inline node_type find_node(node_type c)
const {
284 LIBSEMIGROUPS_ASSERT(is_valid_node(c));
286 node_type d = _ident[c];
290 node_type e = _ident[d];
297 LIBSEMIGROUPS_ASSERT(is_active_node(c));
301 void add_active_nodes(
size_t);
302 void add_free_nodes(
size_t);
303 void erase_free_nodes();
304 node_type new_active_node();
306 void switch_nodes(node_type
const, node_type
const);
308 void apply_permutation(Perm p);
311 void free_node(node_type
const);
319 constexpr node_type initial_node() const noexcept {
323 static constexpr node_type _id_node = 0;
325 node_type _current_la;
328 struct ActiveNodesRange {
329 using output_type = node_type;
331 NodeManager
const* _node_manager;
332 output_type _current;
334 ActiveNodesRange() : _node_manager(nullptr), _current(
UNDEFINED) {}
336 explicit ActiveNodesRange(NodeManager
const* nm)
337 : _node_manager(nm), _current(nm->initial_node()) {}
339 output_type get() const noexcept {
343 void next() noexcept {
344 _current = _node_manager->next_active_node(_current);
347 bool at_end() const noexcept {
348 return _node_manager ==
nullptr
349 || _current == _node_manager->first_free_node();
352 size_t size_hint() const noexcept {
353 return _node_manager->number_of_nodes_active();
356 static constexpr bool is_finite =
true;
357 static constexpr bool is_idempotent =
true;
361 ActiveNodesRange active_nodes()
const {
362 return ActiveNodesRange(
this);
377 size_t _nodes_killed;
380 float _growth_factor;
383 std::vector<node_type> _bckwd;
384 node_type _first_free_node;
385 std::vector<node_type> _forwd;
386 mutable std::vector<node_type> _ident;
387 node_type _last_active_node;
389#ifdef LIBSEMIGROUPS_DEBUG
395 void debug_validate_forwd_bckwd()
const;
402#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
405struct rx::is_input_range<
406 typename
libsemigroups::detail::NodeManager<uint32_t>::ActiveNodesRange>
409#include "node-manager.tpp"
Undefined const UNDEFINED
Value for something undefined.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44