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