22template<
typename TAllocator,
typename T,
typename TNodeHandler, Recycling TRecycling>
97 +
reinterpret_cast<std::size_t
>(key.
parent) * 29;
178 while( childIt != &
children.hook ) {
179 if( childIt->
name.
key.
template Equals<NC>( childName ) )
181 childIt= childIt->
next();
189 return childIt != tree->
nodeTable.end() ? &childIt.Value()
198 while(
p !=
nullptr ) {
213 while(
p !=
nullptr ) {
234 template<
typename... TArgs>
238 auto childCreation= tree->
nodeTable.EmplaceIfNotExistent(
NodeKey(
this, childName),
239 std::forward<TArgs>(args)...);
240 NodeBase* child= &childCreation.first.Value();
242 if( childCreation.second ) {
243 TNodeHandler::InitializeNode( *
static_cast<Node*
>(child), *tree );
248 return std::make_pair( child, childCreation.second );
261 "STRINGTREE",
"This node has no children to remove")
263 "STRINGTREE",
"The given node is not a child of this node.")
268 auto handle= tree->
nodeTable.Extract( *child );
270 TNodeHandler::FreeNode( handle.Value(), *tree );
286 count+= child->deleteChildren( tree );
288 TNodeHandler::FreeNode( handle.Value(), *tree );
289 child= child->next();
314 static constexpr int STACK_SIZE= 32;
318 if (childNode == maxParent)
323 nStack[0] = childNode;
324 while( childNode->
parent != maxParent ) {
325 childNode= childNode->
parent;
326 if( childNode ==
nullptr)
330 if(sp == STACK_SIZE) {
331 assemblePath( target, childNode, maxParent, separatorChar );
334 nStack[sp++]= childNode;
339 if( nStack[sp]->
parent !=
nullptr ) {
340 if( target.CharAtEnd() != separatorChar
341 && nStack[sp]->
parent != maxParent )
342 target << separatorChar;
344 target << nStack[sp]->
name.
key;
347 target << separatorChar;
374 template<
typename... TArgs>
377 ,
data ( std::forward<TArgs>(args)... ) {}
384 template<
typename... TArgs>
387 ,
data ( std::forward<TArgs>(args)... ) {}
429 typename NodeKey::ValueDescriptor,
430 typename NodeKey::Hash,
431 typename NodeKey::EqualTo,
450 template<
bool TConst>
454 using cmTree = std::conditional_t<!TConst, StringTreeBase, const StringTreeBase>;
458 using cmNodeBase = std::conditional_t<!TConst, NodeBase, const NodeBase>;
461 using cmNode = std::conditional_t<!TConst, Node, const Node>;
519 if( path.CharAtStart() ==
tree->separator ) {
520 path.ConsumeChars( 1 );
521 while( actNode->parent != nullptr )
522 actNode= actNode->parent;
528 while(path.ConsumeChar( tree->separator ) )
532 return static_cast<cmNode*>(actNode);
535 NameType name=path.template Substring<NC>(0, path.IndexOfOrLength(tree->separator));
538 if( name.Length() == 2 && name[0] ==
'.' && name[1] ==
'.' ) {
541 if( actNode->parent != nullptr )
542 actNode= actNode->parent;
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);
553 path.ConsumeChars( name.Length() );
573 template<
typename... TArgs,
bool TRequires= !TConst >
576 std::pair<cmNodeBase*, int> result= std::make_pair(
node, 0 );
582 if( rest.CharAtStart() ==
tree->separator ) {
583 rest.ConsumeChars( 1 );
584 while( actNode->parent !=
nullptr )
585 actNode= actNode->parent;
591 while(rest.ConsumeChar(
tree->separator ) )
597 rest.IndexOfOrLength(
tree->separator ) );
601 if( childName[0] ==
'.' )
604 if( childName.
Length() == 1 )
606 if( childName.
Length() == 2 && childName[1] !=
'.' ) {
607 if ( !actNode->isRoot() )
608 actNode= actNode->parent;
612 auto childCreation= actNode->findOrCreateChild(
tree, childName,
613 std::forward<TArgs>(args)... );
615 if( childCreation.second )
618 actNode= childCreation.first;
619 rest.ConsumeChars( childName.
Length() + 1);
643 template<
typename TSharedRecycler= SharedRecyclerType>
644 requires ( !std::same_as<TSharedRecycler , void> )
653 template<
typename TSharedRecycler= SharedRecyclerType>
654 requires (!std::same_as<TSharedRecycler, void>)
671 && ( name.
Length() == 1 || ( name[1] ==
'.'
672 && name.
Length() == 2 ) ) )
675 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
TConst
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.