22template<
typename TAllocator,
typename T,
typename TNodeHandler, Recycling TRecycling>
101 +
reinterpret_cast<std::size_t
>(key.
parent) * 29;
184 while( childIt != &
children.hook ) {
185 if( childIt->
name.
key.
template Equals<NC>( childName ) )
187 childIt= childIt->
next();
195 return childIt != tree->
nodeTable.end() ? &childIt.Value()
204 while(
p !=
nullptr ) {
219 while(
p !=
nullptr ) {
240 template<
typename... TArgs>
244 auto childCreation= tree->
nodeTable.EmplaceIfNotExistent(
NodeKey(
this, childName),
245 std::forward<TArgs>(args)...);
246 NodeBase* child= &childCreation.first.Value();
248 if( childCreation.second ) {
249 TNodeHandler::InitializeNode( *
static_cast<Node*
>(child), *tree );
254 return std::make_pair( child, childCreation.second );
267 "STRINGTREE",
"This node has no children to remove")
269 "STRINGTREE",
"The given node is not a child of this node.")
274 auto handle= tree->
nodeTable.Extract( *child );
276 TNodeHandler::FreeNode( handle.Value(), *tree );
292 count+= child->deleteChildren( tree );
294 TNodeHandler::FreeNode( handle.Value(), *tree );
295 child= child->next();
320 static constexpr int STACK_SIZE= 32;
324 if (childNode == maxParent)
329 nStack[0] = childNode;
330 while( childNode->
parent != maxParent ) {
331 childNode= childNode->
parent;
332 if( childNode ==
nullptr)
336 if(sp == STACK_SIZE) {
337 assemblePath( target, childNode, maxParent, separatorChar );
340 nStack[sp++]= childNode;
345 if( nStack[sp]->
parent !=
nullptr ) {
346 if( target.CharAtEnd() != separatorChar
347 && nStack[sp]->
parent != maxParent )
348 target << separatorChar;
350 target << nStack[sp]->
name.
key;
353 target << separatorChar;
381 template<
typename... TArgs>
384 ,
data ( std::forward<TArgs>(args)... ) {}
391 template<
typename... TArgs>
394 ,
data ( std::forward<TArgs>(args)... ) {}
437 typename NodeKey::ValueDescriptor,
438 typename NodeKey::Hash,
439 typename NodeKey::EqualTo,
458 template<
bool TConst>
463 using cmTree = std::conditional_t<!TConst, StringTreeBase, const StringTreeBase>;
467 using cmNodeBase = std::conditional_t<!TConst, NodeBase, const NodeBase>;
470 using cmNode = std::conditional_t<!TConst, Node, const Node>;
528 if( path.CharAtStart() ==
tree->separator ) {
529 path.ConsumeChars( 1 );
530 while( actNode->parent != nullptr )
531 actNode= actNode->parent;
537 while(path.ConsumeChar( tree->separator ) )
541 return static_cast<cmNode*>(actNode);
544 NameType name=path.template Substring<NC>(0, path.IndexOfOrLength(tree->separator));
547 if( name.Length() == 2 && name[0] ==
'.' && name[1] ==
'.' ) {
550 if( actNode->parent != nullptr )
551 actNode= actNode->parent;
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);
562 path.ConsumeChars( name.Length() );
582 template<
typename... TArgs,
bool TRequires= !TConst >
584 std::pair<cmNodeBase*, int>
586 std::pair<cmNodeBase*, int> result= std::make_pair(
node, 0 );
592 if( rest.CharAtStart() ==
tree->separator ) {
593 rest.ConsumeChars( 1 );
594 while( actNode->parent !=
nullptr )
595 actNode= actNode->parent;
601 while(rest.ConsumeChar(
tree->separator ) )
607 rest.IndexOfOrLength(
tree->separator ) );
611 if( childName[0] ==
'.' )
614 if( childName.
Length() == 1 )
616 if( childName.
Length() == 2 && childName[1] !=
'.' ) {
617 if ( !actNode->isRoot() )
618 actNode= actNode->parent;
622 auto childCreation= actNode->findOrCreateChild(
tree, childName,
623 std::forward<TArgs>(args)... );
625 if( childCreation.second )
628 actNode= childCreation.first;
629 rest.ConsumeChars( childName.
Length() + 1);
653 template<
typename TSharedRecycler= SharedRecyclerType>
654 requires ( !std::same_as<TSharedRecycler , void> )
663 template<
typename TSharedRecycler= SharedRecyclerType>
664 requires (!std::same_as<TSharedRecycler, void>)
681 && ( name.
Length() == 1 || ( name[1] ==
'.'
682 && name.
Length() == 2 ) ) )
685 ALIB_WARNING(
"STRINGTREE",
"Illegal child name \"{}\".", name )
#define ALIB_ASSERT(cond, domain)
#define ALIB_WARNING(domain,...)
#define ALIB_ALLOW_UNINITIALIZED
#define ALIB_POP_ALLOWANCE
#define ALIB_ASSERT_ERROR(cond, domain,...)
constexpr integer Length() const
constexpr bool IsEmpty() const
integer IndexOf(TChar needle, integer startIdx=0) const
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.
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)
NodeBase(const NodeKey &pKey)
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)
uinteger deleteChildren(StringTreeBase *tree)
int distance(const NodeBase *other) const
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
ValueDescriptor for hash table #"nodeTable".
NodeKey & Key(NodeBase &src) 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.
cmNode * followPath(SubstringType &path) const
TCursorBase(cmNode *pNode, cmTree *pTree) noexcept
std::conditional_t<!TConst, StringTreeBase, const StringTreeBase > cmTree
TCursorBase(TCursorBase &&) noexcept=default
Trivial default move constructor.
TAllocator & GetAllocator() noexcept
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.
void next(SidiNodeBase *p)
integer count(SidiNodeBase *end=nullptr) const noexcept
NameType key
The name to compare when just keys are used.
NameStorageType storage
The name when stored in the hashtable.
NodeNameUnion(const NodeNameUnion &n)
Copy constructor.
~NodeNameUnion()
Destructor.
NodeNameUnion(const NameType &n)
Constructor taking a key string.
~RootNodeSpacer()
Destructor.
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.