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;
325 nStack[0] = childNode;
326 while( childNode->
parent != maxParent ) {
327 childNode= childNode->
parent;
328 if( childNode ==
nullptr)
332 if(sp == STACK_SIZE) {
333 assemblePath( target, childNode, maxParent, separatorChar );
336 nStack[sp++]= childNode;
341 if( nStack[sp]->
parent !=
nullptr ) {
342 if( target.CharAtEnd() != separatorChar
343 && nStack[sp]->
parent != maxParent )
344 target << separatorChar;
346 target << nStack[sp]->
name.
key;
349 target << separatorChar;
377 template<
typename... TArgs>
380 ,
data ( std::forward<TArgs>(args)... ) {}
387 template<
typename... TArgs>
390 ,
data ( std::forward<TArgs>(args)... ) {}
433 typename NodeKey::ValueDescriptor,
434 typename NodeKey::Hash,
435 typename NodeKey::EqualTo,
454 template<
bool TConst>
459 using cmTree = std::conditional_t<!TConst, StringTreeBase, const StringTreeBase>;
463 using cmNodeBase = std::conditional_t<!TConst, NodeBase, const NodeBase>;
466 using cmNode = std::conditional_t<!TConst, Node, const Node>;
524 if( path.CharAtStart() ==
tree->separator ) {
525 path.ConsumeChars( 1 );
526 while( actNode->parent != nullptr )
527 actNode= actNode->parent;
533 while(path.ConsumeChar( tree->separator ) )
537 return static_cast<cmNode*>(actNode);
540 NameType name=path.template Substring<NC>(0, path.IndexOfOrLength(tree->separator));
543 if( name.Length() == 2 && name[0] ==
'.' && name[1] ==
'.' ) {
546 if( actNode->parent != nullptr )
547 actNode= actNode->parent;
550 else if( name.Length() != 1 || name[0] !=
'.' ) {
551 cmNodeBase* child= actNode->findChild( tree, name );
552 if( child == nullptr )
553 return static_cast<cmNode*>(actNode);
558 path.ConsumeChars( name.Length() );
578 template<
typename... TArgs,
bool TRequires= !TConst >
580 std::pair<cmNodeBase*, integer>
582 std::pair<cmNodeBase*, integer> result= std::make_pair(
node, 0 );
588 if( rest.CharAtStart() ==
tree->separator ) {
589 rest.ConsumeChars( 1 );
590 while( actNode->parent !=
nullptr )
591 actNode= actNode->parent;
597 while(rest.ConsumeChar(
tree->separator ) )
603 rest.IndexOfOrLength(
tree->separator ) );
607 if( childName[0] ==
'.' )
610 if( childName.
Length() == 1 )
612 if( childName.
Length() == 2 && childName[1] !=
'.' ) {
613 if ( !actNode->isRoot() )
614 actNode= actNode->parent;
618 auto childCreation= actNode->findOrCreateChild(
tree, childName,
619 std::forward<TArgs>(args)... );
621 if( childCreation.second )
624 actNode= childCreation.first;
625 rest.ConsumeChars( childName.
Length() + 1);
649 template<
typename TSharedRecycler= SharedRecyclerType>
650 requires ( !std::same_as<TSharedRecycler , void> )
659 template<
typename TSharedRecycler= SharedRecyclerType>
660 requires (!std::same_as<TSharedRecycler, void>)
677 && ( name.
Length() == 1 || ( name[1] ==
'.'
678 && name.
Length() == 2 ) ) )
681 ALIB_WARNING(
"STRINGTREE",
"Illegal child name \"{}\".", name )
constexpr integer Length() const
constexpr bool IsEmpty() const
integer IndexOf(TChar needle, integer startIdx=0) const
std::size_t Hashcode() const
#define ALIB_WARNINGS_UNINITIALIZED_OFF
#define ALIB_ASSERT(cond, domain)
#define ALIB_WARNINGS_RESTORE
#define ALIB_WARNING(domain,...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
Detail namespace of module ALib Containers.
@ Enabled
Caching is enabled.
lang::uinteger uinteger
Type alias in namespace alib.
strings::TSubstring< character > Substring
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::conditional_t<!TConst, NodeBase, const NodeBase > cmNodeBase
std::pair< cmNodeBase *, integer > followPathCreate(const NameType &path, TArgs &&... args)
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
lang::BidiListHook< NodeBase > NodeList
Alias shortcut for a bidirectional list of Node elements.
StringTreeBase(TAllocator &allocator, TSharedRecycler &pRecycler, CharacterType pathSeparator)
typename decltype(nodeTable)::SharedRecyclerType SharedRecyclerType
typename TNodeHandler::CharacterType CharacterType
StringTreeBase(TSharedRecycler &pRecycler, CharacterType pathSeparator)
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<TConst>.
TCursorBase< true > ConstCursorBase
The constant version of type StringTreeBase::TCursorBase<TConst>.
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.