ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
stringtreebase.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_containers of the \aliblong.
4///
5/// Copyright 2013-2026 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
9
10/// Base struct of #"StringTree" providing internals.
11/// \note
12/// The separation of the internals of class #"%StringTree" to this type in namespace
13/// #"%containers::detail" has no benefit on compilation speed or other positive "technical"
14/// effect, nor is it a matter of software design.<br>
15/// The motivation is that a user of derived class #"HashTable" finds all interface methods and
16/// types in one place, which is not cluttered by the documentation of the internals found here.
17/// Otherwise, the separation is exclusively supporting source code organization.
18///
19/// @see For a description of the template parameters and a general introduction to the topic,
20/// se the reference documentation of the derived main class
21/// #"StringTree".
22template<typename TAllocator, typename T, typename TNodeHandler, Recycling TRecycling>
24 //################################################################################################
25 // Inner types
26 //################################################################################################
27 struct NodeBase; // forward declaration
28 struct Node; // forward declaration
29
30 /// Alias shortcut for a bidirectional list of #"%Node" elements.
32
33 /// The character type of node names and paths strings. This is defined using character type
34 /// definition #"StringTreeNamesDynamic::CharacterType" of template type
35 /// \p{TNodeHandler}.
36 using CharacterType = typename TNodeHandler::CharacterType;
37
38 /// The string-type of node names and paths if provided externally for comparison.
40
41 /// The string-type of node names and paths. This is defined by
42 /// #"StringTreeNamesDynamic::NameStringType" of template type \p{TNodeHandler}.
43 using NameStorageType = typename TNodeHandler::NameStringType;
44
45 /// The substring-type of paths. This is defined using character type definition
46 /// #"StringTreeNamesDynamic::CharacterType" of template type \p{TNodeHandler}.
48
49 /// The unique key to any element stored in this container.
50 /// By being a (second) base type for of type #"StringTreeBase;Node", any
51 /// node includes this key.
52 struct NodeKey {
53 /// The parent node. A value of \c nullptr indicates that this is the root node of
54 /// the tree, which is always existing.
56
57 /// A union of base string and the derived (or same) final storage type. Only the node
58 /// handler will finalize the name into the second field.
60 /// Constructor taking a key string. @param n The name of the node.
61 explicit NodeNameUnion(const NameType& n) : key(n) {}
62
63 /// Copy constructor. @param n The union to copy.
64 explicit NodeNameUnion(const NodeNameUnion& n) : key(n.key) {}
65
66 /// Destructor.
68
69 NameType key; ///< The name to compare when just keys are used.
70 NameStorageType storage; ///< The name when stored in the hashtable
71 };
72
73 /// A string object containing the pointer to this node's name.
74 /// Node names constitute path strings and, together with the pointer to their parent, form
75 /// the key of the hash set found with field #"StringTreeBase;nodeTable".
76 /// <br>
77 /// Node names must not contain the separator character and must not equal to <c>"."</c> or
78 /// <c>".."</c>.
79 ///
80 /// The name of the root node is nulled.
82
83 /// Constructor
84 /// @param pParent Parent node to search a child for.
85 /// @param pName Child name to search
86 NodeKey( NodeBase* pParent, const NameType& pName )
87 : parent(pParent)
88 , name( pName ) {}
89
90 /// Hash functor for nodes hashed in field #"nodeTable".
91 struct Hash {
92 /// Calculates a hash code for #"%NodeKey" objects.
93 /// @param key The key to hash.
94 /// @return The hash code.
95 std::size_t operator()(const NodeKey& key) const {
96 return key.name.key.Hashcode()
97 + reinterpret_cast<std::size_t>(key.parent) * 29;
98 }
99 };
100
101 /// Equality functor for nodes in field #"nodeTable".
102 struct EqualTo {
103 /// Invokes #"TString::Equals;String::Equals" on \p{lhs}, passing \p{rhs}
104 /// and returns the result.
105 /// @param lhs The first string object.
106 /// @param rhs The second string object.
107 /// @return The result of the string comparison.
108 bool operator()(const NodeKey& lhs,
109 const NodeKey& rhs ) const
110 {
111 return lhs.parent == rhs.parent
112 && lhs.name.key. template Equals<NC>( rhs.name.key );
113 }
114 };
115
116 /// ValueDescriptor for hash table #"nodeTable".
118 /// Casts given \p{src} down to its base class
119 /// #"StringTreeBase;NodeKey".
120 /// @param src The node to receive the key-portion for.
121 /// @return The key-portion of the node.
122 NodeKey& Key( NodeBase& src ) const { return static_cast<NodeKey&>( src ); }
123 };
124 };
125
126 /// This is the base class of the internal node type #"StringTreeBase;Node".
127 /// This type implements functionality needed. Derived type #"%Node" then only adds the custom
128 /// value \p{T}.
129 ///
130 /// Objects of this type cannot be received directly and all interface is available
131 /// via public type #"StringTree::Cursor;*" only, which holds a pointer to
132 /// an object of this class.
134 public NodeKey
135 {
136 /// The number of children currently stored in this node.
138
139 /// The hook to the doubly linked list of children.
141
142 /// Constructor.
143 /// @param pKey The key portion of the node.
144 NodeBase(const NodeKey& pKey)
145 : NodeKey ( pKey )
146 , qtyChildren(0) {}
147
148 /// Constructor. Custom data is default-initialized.
149 /// @param pParent Parent node to search a child for.
150 /// @param pName Child name to search
151 NodeBase( NodeBase* pParent, const NameType& pName)
152 : NodeKey ( pParent, pName )
153 , qtyChildren(0) {}
154
155 /// Returns \c true if this is the root node, \c false otherwise.
156 /// @return \c true if this is the root node, \c false otherwise.
157 bool isRoot() const { return NodeKey::parent == nullptr; }
158
159 /// Searches a child with a given name.
160 /// The name is not checked for <c>.</c>, <c>..</c> or if separation characters.
161 ///
162 /// @param tree The tree this node belongs to.
163 /// @param childName The name of the child to search.
164 /// @return The child or \c nullptr if not found.
165 NodeBase* findChild( StringTreeBase* tree, const NameType& childName ) {
166 if( qtyChildren == 0 )
167 return nullptr;
168
169 // With a small number of children, the search is faster if we iterate, because
170 // a) no hash value has to be calculated and
171 // b) the string compare is fast, at least if string have different length or are
172 // different at the beginning.
173 // A good value is probably five children. With bigger numbers, it soon becomes better
174 // to calculate the hash value. While in the bucket also children of other nodes
175 // are found, each entry of the hashtable is first compared against the full hash code.
176 if( qtyChildren <= 5 ) {
177 NodeBase* childIt= children.first();
178 while( childIt != &children.hook ) {
179 if( childIt->name.key. template Equals<NC>( childName ) )
180 return childIt;
181 childIt= childIt->next();
182 }
183
184 return nullptr;
185 }
186
187 // search in hash table
188 auto childIt= tree->nodeTable.Find( NodeKey( this, childName ) );
189 return childIt != tree->nodeTable.end() ? &childIt.Value()
190 : nullptr;
191 }
192
193 /// Iterates over the parent nodes to the root node and returns this node's depth.
194 /// @return The depth of this node.
195 int depth() const {
196 int result= -1;
197 const NodeBase* p= this;
198 while( p != nullptr ) {
199 ++result;
200 p= p->parent;
201 }
202 return result;
203 }
204
205 /// Iterates over the parent nodes and searches given \p{other} in the path.
206 /// @param other The node to calculate the distance to.
207 /// @return The distance of \p{other} to this node.
208 /// \c 0 if the nodes are the same.
209 /// \c -1 if \p{other} was not found.
210 int distance( const NodeBase* other ) const {
211 int result= 0;
212 const NodeBase* p= this;
213 while( p != nullptr ) {
214 if( p == other )
215 return result;
216 ++result;
217 p= p->parent;
218 }
219 return -1;
220 }
221
222 /// Searches a child with a given name, if not found, one is created.
223 /// The name is not checked for <c>.</c>, <c>..</c> or if separation characters.
224 ///
225 /// @tparam TArgs Types of variadic parameters given with parameter \p{args}.
226 /// @param tree The tree this node belongs to.
227 /// @param childName The name of the child to search.
228 /// @param args Variadic parameters to be forwarded to the constructor of custom type
229 /// \p{T} in the case a child is created.
230 /// @return A pair containing an iterator referencing either the element found or the new
231 /// element added.
232 /// The bool component is \c true if the insertion took place and \c false nothing
233 /// was changed.
234 template<typename... TArgs>
235 std::pair<NodeBase*,bool> findOrCreateChild( StringTreeBase* tree,
236 const NameType& childName,
237 TArgs&&... args ) {
238 auto childCreation= tree->nodeTable.EmplaceIfNotExistent( NodeKey(this, childName),
239 std::forward<TArgs>(args)...);
240 NodeBase* child= &childCreation.first.Value();
241
242 if( childCreation.second ) {
243 TNodeHandler::InitializeNode( *static_cast<Node*>(child), *tree );
244 children.pushEnd( child );
245 ++qtyChildren;
246 }
247
248 return std::make_pair( child, childCreation.second );
249 }
250
251 /// Deletes a given child node.
252 /// \note
253 /// If the given node is not a child of this node, the behavior is undefined.
254 /// With debug-builds, in this case an \alib_assertion is raised.
255 ///
256 /// @param tree The tree this node belongs to.
257 /// @param child A pointer to a child of this node that is to be deleted.
258 /// @return The total number of nodes deleted.
261 "STRINGTREE", "This node has no children to remove")
262 ALIB_ASSERT_ERROR( child->parent == this,
263 "STRINGTREE", "The given node is not a child of this node.")
264
265 --qtyChildren;
266 child->remove(); // remove from linked list
267 auto count= child->deleteChildren( tree );
268 auto handle= tree->nodeTable.Extract( *child );
269 ALIB_ASSERT( !handle.IsEmpty(), "STRINGTREE" )
270 TNodeHandler::FreeNode( handle.Value(), *tree );
271
272 return count + 1;
273 }
274
275 /// Deletes all child nodes.
276 /// @param tree The tree this node belongs to.
277 /// @return The number of children that were deleted.
279 if( children.isEmpty() )
280 return 0;
281
283
284 auto* child= children.first();
285 while( child != &children.hook ) {
286 count+= child->deleteChildren( tree ); // recursion
287 auto handle= tree->nodeTable.Extract( *child ); ALIB_ASSERT( !handle.IsEmpty(), "STRINGTREE")
288 TNodeHandler::FreeNode( handle.Value(), *tree );
289 child= child->next();
290 --qtyChildren;
291 }
292
293 ALIB_ASSERT(qtyChildren == 0, "STRINGTREE")
294 children.reset();
295 return count;
296 }
297
298 /// Implementation of
299 /// #"TCursor::AssemblePath(const TCursor)".
300 ///
301 /// @param target The target to append the path to.
302 /// @param childNode The (current) child node.
303 /// @param maxParent The last parent node to travel up to. The root node is designated
304 /// by \c nullptr.
305 /// @param separatorChar The separator character as defined with the template parameter of
306 /// class #"StringTree".
307 /// @return The given #"%AString" to allow concatenated operations on it.
310 lang::HeapAllocator>& target,
311 const NodeBase* childNode,
312 const NodeBase* maxParent,
313 CharacterType separatorChar ) const {
314 static constexpr int STACK_SIZE= 32;
315 const NodeBase* nStack[STACK_SIZE];
316
317 // if child and maxParent are the same, we do nothing
318 if (childNode == maxParent)
319 return target;
320
321 // build stack
322 int sp =1;
323 nStack[0] = childNode;
324 while( childNode->parent != maxParent ) {
325 childNode= childNode->parent;
326 if( childNode == nullptr)
327 break;
328
329 // local stack full? -> let a recursive call do the rest
330 if(sp == STACK_SIZE) {
331 assemblePath( target, childNode, maxParent, separatorChar );
332 break;
333 }
334 nStack[sp++]= childNode;
335 }
336
337 // unroll stack now from top to bottom
338 while( --sp >= 0) {
339 if( nStack[sp]->parent != nullptr ) {
340 if( target.CharAtEnd() != separatorChar
341 && nStack[sp]->parent != maxParent )
342 target << separatorChar;
343
344 target << nStack[sp]->name.key;
345 }
346 else
347 target << separatorChar;
348 }
349
350 return target;
351 }
352 }; // inner class NodeBase
353
354 /// This is the "final" internal node type, just adds a field of template type \p{T}
355 /// to its base class.
356 ///
357 /// Objects of this type cannot be received directly, and all interfaces are available
358 /// via public type #"StringTree::Cursor;*" only, which holds a pointer to
359 /// an object of this class.
360 struct Node : public NodeBase {
361 /// The templated custom data object stored with each node.
363
364 /// Deleted copy constructor.
365 Node( const Node& ) =delete;
366
367 /// Deleted move constructor.
368 Node( Node&& ) =delete;
369
370 /// Constructor. Custom data is default-initialized.
371 /// @tparam TArgs Types of variadic parameters given with parameter \p{args}.
372 /// @param pKey The key portion of the node.
373 /// @param args Variadic parameters. Forwarded to the constructor of custom type \p{T}.
374 template<typename... TArgs>
375 Node( const NodeKey& pKey, TArgs&&... args )
376 : NodeBase( pKey )
377 , data ( std::forward<TArgs>(args)... ) {}
378
379 /// Constructor. Custom data is default-initialized.
380 /// @tparam TArgs Types of variadic parameters given with parameter \p{args}.
381 /// @param pParent Parent node to search a child for.
382 /// @param pName Child name to search
383 /// @param args Variadic parameters. Forwarded to the constructor of custom type \p{T}.
384 template<typename... TArgs>
385 Node( NodeBase* pParent, const NameType& pName, TArgs&&... args )
386 : NodeBase( pParent, pName )
387 , data ( std::forward<TArgs>(args)... ) {}
388
389 }; // inner class Node
390
391 //################################################################################################
392 // StringTreeBase: members
393 //################################################################################################
394 /// This is a union of either a node with a custom object or without. This tricks us into the
395 /// position to embed the memory for a custom type which may optionally be assigned to the root
396 /// node, without constructing it.
397 /// Construction will only be done with explicit use of method
398 /// #"StringTree::ConstructRootValue;*".
400 NodeBase rootBase; ///< Base version of the root node, which becomes initialized.
401 Node root; ///< Full version of the root node, without initialization of member T.
402
403 /// Explicitly implement otherwise implicitly deleted constructor
404 RootNodeSpacer() : rootBase( nullptr, nullptr) {}
405
406 /// Destructor
408 };
409
410 /// The root node.
411 RootNodeSpacer root;
412
413 #if ALIB_DEBUG
414 /// Flag available only in debug-compilations to detect access to root node's value
415 /// without prior use of method #"StringTree::ConstructRootValue". Also, the
416 /// destructor issues a warning, in case the root node's value was not deleted with
417 /// #"StringTree::DestructRootValue".
419 #endif
420
421
422 /// The separator character to use with path strings.
423 /// This is set once with construction.
425
426 /// Hash set which contains all children of all nodes.
427 /// This is used to find children of nodes by their parent/name combination.
428 HashTable< TAllocator,
429 typename NodeKey::ValueDescriptor,
430 typename NodeKey::Hash,
431 typename NodeKey::EqualTo,
433 TRecycling > nodeTable;
434
435 /// This type definition may be used to define an externally managed shared recycler,
436 /// which can be passed to the alternative constructor of this class when template
437 /// parameter \p{TRecycling} equals #"Recycling::Shared".
438 /// \see
439 /// Chapter #"alib_contmono_containers_recycling_shared" of the Programmer's Manual
440 /// for this \alibmod.
442
443
444 //################################################################################################
445 // class TCursorBase
446 //################################################################################################
447 /// Base class for #"StringTree::Cursor;*"
448 /// @tparam TConst If true, internal fields representing the StringTree and the current Node
449 /// become \c const and the method #"followPathCreate" becomes unavailable.
450 template<bool TConst>
451 struct TCursorBase {
452 /// Constant or mutable version of the base tree type, depending on template parameter
453 /// \p{TConst}
454 using cmTree = std::conditional_t<!TConst, StringTreeBase, const StringTreeBase>;
455
456 /// Constant or mutable version of type #"%NodeBase", depending on template parameter
457 /// \p{TConst}
458 using cmNodeBase = std::conditional_t<!TConst, NodeBase, const NodeBase>;
459
460 /// Constant or mutable version of type #"%Node", depending on template parameter \p{TConst}
461 using cmNode = std::conditional_t<!TConst, Node, const Node>;
462
463 /// The currently represented node of the #".tree".
465
466 /// The #"%StringTree" this object refers to.
468
469 /// Constructor initializing both fields #".tree" and #".node".
470 /// @param pNode The node to refer to.
471 /// @param pTree The #"%StringTree" we work on.
472 TCursorBase( cmNode* pNode, cmTree* pTree) noexcept
473 : node( pNode )
474 , tree( pTree ) {}
475
476 /// Default constructor. Creates an invalid (uninitialized) object.
477 TCursorBase() noexcept
478 : node( nullptr )
479 , tree( nullptr ) {}
480
481 /// Trivial default copy constructor.
482 TCursorBase( const TCursorBase& ) noexcept =default;
483
484 /// Trivial default move constructor.
485 TCursorBase( TCursorBase&& ) noexcept =default;
486
487 /// Trivial default copy assign operator.
488 /// @return A reference to \c this.
489 TCursorBase& operator=( const TCursorBase& ) noexcept =default;
490
491 /// Trivial default move assign operator.
492 /// @return A reference to \c this.
493 TCursorBase& operator=( TCursorBase&& ) noexcept =default;
494
495 /// Trivial default destructor.
496 ~TCursorBase() noexcept =default;
497
498
499 /// Finds a child node along the \p{path} given, but does not create new nodes.
500 /// Incomplete results may occur if a child along the path was not found.
501 /// In this case, parameter \p{path} contains the remaining path, excluding a leading
502 /// separator.
503 ///
504 /// A leading slash (aka \p{TSeparator}) allows absolute path addressing, which means
505 /// the root of \p{node} is searched if a leading separator is found.
506 ///
507 /// Besides normal child names, this method accepts
508 /// - multiple separator characters (ignored)
509 /// - child name "." (ignored)
510 /// - child name ".." for parent node
511 ///
512 /// @param[in,out] path Creation path. Provided as reference and consumed as far
513 /// as the path exits.
514 /// @return The node found
516 cmNodeBase* actNode= node;
517
518 // check for "root addressing"
519 if( path.CharAtStart() == tree->separator ) {
520 path.ConsumeChars( 1 );
521 while( actNode->parent != nullptr )
522 actNode= actNode->parent;
523 }
524
525 // loop over node names in path
526 for(;;) {
527 // multiple separators are ignored
528 while(path.ConsumeChar( tree->separator ) )
529 ;
530
531 if( path.IsEmpty() )
532 return static_cast<cmNode*>(actNode);
533
534
535 NameType name=path.template Substring<NC>(0, path.IndexOfOrLength(tree->separator));
536
537
538 if( name.Length() == 2 && name[0] == '.' && name[1] == '.' ) {
539 // we move up only if possible. If not, the ".." is just ignored (consumed)
540 // (This behavior was just more helpful in the use cases so far)
541 if( actNode->parent != nullptr )
542 actNode= actNode->parent;
543 }
544
545 else if( name.Length() != 1 || name[0] != '.' ) {
546 cmNodeBase* child= actNode->findChild( tree, name );
547 if( child == nullptr )
548 return static_cast<cmNode*>(actNode);
549
550 actNode= child;
551 }
552
553 path.ConsumeChars( name.Length() );
554 } }
555
556 /// Follows the given path and creates non-existing children along the way.
557 ///
558 /// Child names <c>"."</c> and <c>".."</c> are allowed and respected same
559 /// as in #".followPath".
560 ///
561 /// New child nodes are constructed by forwarding the given \p{args}. Existing children
562 /// remain untouched.
563 ///
564 /// \note This method is only available if the template parameter \p{TConst} of this
565 /// type is \c false.
566 /// @tparam TRequires Defaulted template parameter. Must not be specified.
567 /// @tparam TArgs Types of variadic parameters given with parameter \p{args}.
568 /// @param path The path to move along.
569 /// @param args Variadic parameters to be forwarded to the constructor of each node
570 /// that is created.
571 /// @return A <c>std::pair</c> containing a resulting #"%Node"* and the number of nodes
572 /// created.
573 template<typename... TArgs, bool TRequires= !TConst >
574 requires TRequires
575 std::pair<cmNodeBase*, int> followPathCreate( const NameType& path, TArgs&&... args ) {
576 std::pair<cmNodeBase*, int> result= std::make_pair( node, 0 );
577 cmNodeBase*& actNode= result.first; // a local alias name, let the compiler decide
578
579 SubstringType rest= path;
580
581 // check for "root addressing"
582 if( rest.CharAtStart() == tree->separator ) {
583 rest.ConsumeChars( 1 );
584 while( actNode->parent != nullptr )
585 actNode= actNode->parent;
586 }
587
588 // loop over path string
589 for(;;) {
590 // consume '/' and check for emptiness
591 while(rest.ConsumeChar( tree->separator ) )
592 ;
593 if( rest.IsEmpty() )
594 return result;
595
596 NameType childName= rest.template Substring<NC>( 0,
597 rest.IndexOfOrLength( tree->separator ) );
598
599 // "." or ".."?
601 if( childName[0] == '.' )
603 {
604 if( childName.Length() == 1 )
605 continue;
606 if( childName.Length() == 2 && childName[1] != '.' ) {
607 if ( !actNode->isRoot() )
608 actNode= actNode->parent;
609 continue;
610 } }
611
612 auto childCreation= actNode->findOrCreateChild( tree, childName,
613 std::forward<TArgs>(args)... );
614
615 if( childCreation.second )
616 ++result.second;
617
618 actNode= childCreation.first;
619 rest.ConsumeChars( childName.Length() + 1);
620 } }
621 }; // inner class TCursorBase
622
623 /// The mutable version of type #"StringTreeBase::TCursorBase".
625
626 /// The constant version of type #"StringTreeBase::TCursorBase".
628
629 //################################################################################################
630 // StringTreeBase interface
631 //################################################################################################
632 /// Constructor.
633 /// @param allocator The monotonic allocator to use.
634 /// @param pathSeparator The separation character used with path strings.
635 StringTreeBase( TAllocator& allocator, CharacterType pathSeparator )
636 : separator( pathSeparator )
637 , nodeTable( allocator ) {}
638
639 /// Constructor taking a shared recycler.
640 /// @param allocator The monotonic allocator to use.
641 /// @param pRecycler The shared recycler.
642 /// @param pathSeparator The separation character used with path strings.
643 template<typename TSharedRecycler= SharedRecyclerType>
644 requires ( !std::same_as<TSharedRecycler , void> )
645 StringTreeBase( TAllocator& allocator, TSharedRecycler& pRecycler, CharacterType pathSeparator )
646 : separator( pathSeparator )
647 , nodeTable( allocator, pRecycler ) {}
648
649 /// Constructor taking a shared recycler.
650 /// @param pRecycler The shared recycler.
651 /// @param pathSeparator The separation character used with path strings.
652 /// @tparam TSharedRecycler Used to select this constructor. Deduced by the compiler.
653 template<typename TSharedRecycler= SharedRecyclerType>
654 requires (!std::same_as<TSharedRecycler, void>)
655 StringTreeBase( TSharedRecycler& pRecycler, CharacterType pathSeparator )
656 : separator( pathSeparator )
657 , nodeTable( pRecycler ) {}
658
659 /// @return Returns the allocator received with construction.
660 TAllocator& GetAllocator() noexcept { return nodeTable.GetAllocator(); }
661
662 /// Simple helper method which checks a node name for not being <c>"."</c> or <c>".."</c>
663 /// and for not containing a separator character.
664 /// In debug-compilations, if it does, a #"alib_mod_assert;warning is raised".
665 ///
666 /// @param name The child name to check.
667 /// @return \c true if the name is legal, false otherwise.
668 bool checkChildName( const NameType& name ) const {
669 if( name.IsEmpty()
670 || ( name[0] == '.'
671 && ( name.Length() == 1 || ( name[1] == '.'
672 && name.Length() == 2 ) ) )
673 || name.IndexOf( separator) >=0 )
674 {
675 ALIB_WARNING( "STRINGTREE", "Illegal child name \"{}\".", name )
676 return false;
677 }
678 return true;
679 }
680
681}; // StringTreeBase
682
683
684} // namespace [alib::containers::detail]
#define ALIB_ASSERT(cond, domain)
#define ALIB_WARNING(domain,...)
#define ALIB_ALLOW_UNINITIALIZED
#define ALIB_POP_ALLOWANCE
#define ALIB_EXPORT
#define ALIB_ASSERT_ERROR(cond, domain,...)
constexpr integer Length() const
Definition string.hpp:300
constexpr bool IsEmpty() const
Definition string.hpp:349
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:799
std::size_t Hashcode() const
Detail namespace of module ALib Containers.
@ Enabled
Caching is enabled.
strings::TSubstring< character > Substring
Type alias in namespace #"%alib".
lang::uinteger uinteger
Type alias in namespace #"%alib".
Definition integers.hpp:152
NodeList children
The hook to the doubly linked list of children.
strings::TAString< CharacterType, lang::HeapAllocator > & assemblePath(strings::TAString< CharacterType, lang::HeapAllocator > &target, const NodeBase *childNode, const NodeBase *maxParent, CharacterType separatorChar) const
NodeBase(NodeBase *pParent, const NameType &pName)
uinteger qtyChildren
The number of children currently stored in this node.
uinteger deleteChild(StringTreeBase *tree, NodeBase *child)
NodeBase * findChild(StringTreeBase *tree, const NameType &childName)
std::pair< NodeBase *, bool > findOrCreateChild(StringTreeBase *tree, const NameType &childName, TArgs &&... args)
Equality functor for nodes in field #"nodeTable".
bool operator()(const NodeKey &lhs, const NodeKey &rhs) const
Hash functor for nodes hashed in field #"nodeTable".
std::size_t operator()(const NodeKey &key) const
NodeKey(NodeBase *pParent, const NameType &pName)
Node(const Node &)=delete
Deleted copy constructor.
T data
The templated custom data object stored with each node.
Node(const NodeKey &pKey, TArgs &&... args)
Node(Node &&)=delete
Deleted move constructor.
Node(NodeBase *pParent, const NameType &pName, TArgs &&... args)
TCursorBase() noexcept
Default constructor. Creates an invalid (uninitialized) object.
std::pair< cmNodeBase *, int > followPathCreate(const NameType &path, TArgs &&... args)
std::conditional_t<!TConst, NodeBase, const NodeBase > cmNodeBase
TCursorBase(const TCursorBase &) noexcept=default
Trivial default copy constructor.
std::conditional_t<!TConst, Node, const Node > cmNode
Constant or mutable version of type #"%Node", depending on template parameter TConst.
TCursorBase(cmNode *pNode, cmTree *pTree) noexcept
std::conditional_t<!TConst, StringTreeBase, const StringTreeBase > cmTree
TConst
TCursorBase(TCursorBase &&) noexcept=default
Trivial default move constructor.
typename strings::TSubstring< CharacterType > SubstringType
StringTreeBase(TAllocator &allocator, TSharedRecycler &pRecycler, CharacterType pathSeparator)
typename decltype(nodeTable)::SharedRecyclerType SharedRecyclerType
StringTreeBase(TSharedRecycler &pRecycler, CharacterType pathSeparator)
lang::BidiListHook< NodeBase > NodeList
Alias shortcut for a bidirectional list of #"%Node" elements.
typename TNodeHandler::CharacterType CharacterType
typename TNodeHandler::NameStringType NameStorageType
StringTreeBase(TAllocator &allocator, CharacterType pathSeparator)
const strings::TString< CharacterType > NameType
The string-type of node names and paths if provided externally for comparison.
HashTable< TAllocator, typename NodeKey::ValueDescriptor, typename NodeKey::Hash, typename NodeKey::EqualTo, lang::Caching::Enabled, TRecycling > nodeTable
bool checkChildName(const NameType &name) const
TCursorBase< false > CursorBase
The mutable version of type #"StringTreeBase::TCursorBase".
TCursorBase< true > ConstCursorBase
The constant version of type #"StringTreeBase::TCursorBase".
void remove() noexcept
Unhooks this node from a list.
Definition bidilist.hpp:96
void next(SidiNodeBase *p)
Definition sidilist.hpp:92
integer count(SidiNodeBase *end=nullptr) const noexcept
Definition sidilist.hpp:153
NameType key
The name to compare when just keys are used.
NameStorageType storage
The name when stored in the hashtable.
NodeNameUnion(const NameType &n)
Constructor taking a key string.
Node root
Full version of the root node, without initialization of member T.
RootNodeSpacer()
Explicitly implement otherwise implicitly deleted constructor.
NodeBase rootBase
Base version of the root node, which becomes initialized.