8#ifndef HPP_ALIB_MONOMEM_DETAIL_STRINGTREEBASE
9#define HPP_ALIB_MONOMEM_DETAIL_STRINGTREEBASE 1
11#if !defined(HPP_ALIB_MONOMEM_CONTAINERS_STRINGTREE)
12# error "ALib sources with ending '.inl' must not be included from outside."
21namespace alib {
namespace containers {
37template<
typename TAllocator,
typename T,
typename TNodeHandler, Recycling TRecycling>
118 +
reinterpret_cast<std::size_t
>(key.
parent) * 29;
195 if( qtyChildren == 0 )
205 if( qtyChildren <= 5 )
208 while( childIt != &children.
hook )
210 if( childIt->
name.
key.
template Equals<NC>( childName ) )
212 childIt= childIt->
next();
220 return childIt != tree->
nodeTable.end() ? &childIt.Value()
230 while( p !=
nullptr )
247 while( p !=
nullptr )
269 template<
typename... TArgs>
274 auto childCreation= tree->
nodeTable.EmplaceIfNotExistent(
NodeKey(
this, childName),
275 std::forward<TArgs>(args)...);
276 NodeBase* child= &childCreation.first.Value();
278 if( childCreation.second )
280 TNodeHandler::InitializeNode( *tree, *
static_cast<Node*
>(child ) );
285 return std::make_pair( child, childCreation.second );
299 "This node has no children to remove")
301 "The given node is not a child of this node.")
306 auto handle= tree->
nodeTable.Extract( *child );
308 TNodeHandler::FreeNode( *tree, handle.Value() );
323 auto* child= children.
first();
324 while( child != &children.
hook )
326 count+= child->deleteChildren( tree );
328 TNodeHandler::FreeNode( *tree, handle.Value() );
329 child= child->next();
355 static constexpr int STACK_SIZE= 32;
360 nStack[0] = childNode;
361 while( childNode->
parent != maxParent )
363 childNode= childNode->
parent;
364 if( childNode ==
nullptr)
370 assemblePath( target, childNode, maxParent, separatorChar );
373 nStack[sp++]= childNode;
379 if( nStack[sp]->parent !=
nullptr )
381 if( target.CharAtEnd() != separatorChar
382 && nStack[sp]->
parent != maxParent )
383 target << separatorChar;
385 target << nStack[sp]->
name.
key;
388 target << separatorChar;
416 template<
typename... TArgs>
419 ,
data ( std::forward<TArgs>(args)... )
427 template<
typename... TArgs>
430 ,
data ( std::forward<TArgs>(args)... )
495 template<
bool TConst>
567 if( path.CharAtStart() ==
tree->separator )
569 path.ConsumeChars( 1 );
570 while( actNode->parent != nullptr )
571 actNode= actNode->parent;
578 while(path.ConsumeChar( tree->separator ) )
582 return static_cast<cmNode*>(actNode);
585 NameType name=path.template Substring<NC>(0, path.IndexOfOrLength(tree->separator));
588 if( name.Length() == 2 && name[0] ==
'.' && name[1] ==
'.' )
592 if( actNode->parent != nullptr )
593 actNode= actNode->parent;
596 else if( name.Length() != 1 || name[0] !=
'.' )
598 cmNodeBase* child= actNode->findChild( tree, name );
599 if( child == nullptr )
600 return static_cast<cmNode*>(actNode);
605 path.ConsumeChars( name.Length() );
626 template<
typename... TArgs,
bool TEnableIf= !TConst >
629 template<
typename... TArgs,
bool TEnableIf= !TConst >
630 ATMP_T_IF(std::pair<cmNodeBase* ALIB_COMMA integer>, TEnableIf)
631 followPathCreate(
const NameType& path, TArgs&&... args )
633 std::pair<cmNodeBase*, integer> result= std::make_pair( node, 0 );
639 if( rest.CharAtStart() == tree->separator )
641 rest.ConsumeChars( 1 );
642 while( actNode->parent !=
nullptr )
643 actNode= actNode->parent;
650 while(rest.ConsumeChar( tree->separator ) )
656 rest.IndexOfOrLength( tree->separator ) );
660 if( childName[0] ==
'.' )
663 if( childName.
Length() == 1 )
665 if( childName.
Length() == 2 && childName[1] !=
'.' )
667 if ( !actNode->isRoot() )
668 actNode= actNode->parent;
673 auto childCreation= actNode->findOrCreateChild( tree, childName,
674 std::forward<TArgs>(args)... );
676 if( childCreation.second )
679 actNode= childCreation.first;
680 rest.ConsumeChars( childName.
Length() + 1);
701 : separator( pathSeparator )
702 , nodeTable( allocator )
711 template<
typename TSharedRecycler= SharedRecyclerType,
714 : separator( pathSeparator )
715 , nodeTable( allocator, pRecycler )
723 template<
typename TSharedRecycler= SharedRecyclerType,
726 : separator( pathSeparator )
727 , nodeTable( pRecycler )
731 TAllocator&
GetAllocator() noexcept {
return nodeTable.GetAllocator(); }
743 && ( name.
Length() == 1 || ( name[1] ==
'.'
744 && name.
Length() == 2 ) ) )
745 || name.
IndexOf( separator) >=0 )
747 ALIB_WARNING(
"MONOMEM/STRINGTREE",
"Illegal child name {!Q}", name )
integer IndexOf(TChar needle, integer startIdx=0) const
constexpr bool IsEmpty() const
constexpr integer Length() const
std::size_t Hashcode() const
#define ATMP_IF_T_F( Cond, T, F)
#define ALIB_WARNING(...)
#define ALIB_WARNINGS_UNINITIALIZED_OFF
#define ALIB_WARNINGS_RESTORE
#define ATMP_EQ( T, TEqual)
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_ASSERT(cond)
#define ATMP_T_IF(T, Cond)
@ Enabled
Caching is enabled.
lang::uinteger uinteger
Type alias in namespace alib.
strings::TSubstring< character > Substring
Type alias in namespace alib.
uinteger deleteChild(StringTreeBase *tree, NodeBase *child)
int distance(const NodeBase *other) const
uinteger deleteChildren(StringTreeBase *tree)
strings::TAString< CharacterType, lang::HeapAllocator > & assemblePath(strings::TAString< CharacterType, lang::HeapAllocator > &target, const NodeBase *childNode, const NodeBase *maxParent, CharacterType separatorChar) const
NodeBase(const NodeKey &pKey)
uinteger qtyChildren
The number of children currently stored in this node.
NodeBase * findChild(StringTreeBase *tree, const NameType &childName)
NodeList children
The hook to the doubly linked list of children.
NodeBase(NodeBase *pParent, const NameType &pName)
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
ValueDescriptor for hash table nodeTable.
NodeKey & Key(NodeBase &src) const
NodeKey(NodeBase *pParent, const NameType &pName)
Node(Node &&)=delete
Deleted move constructor.
Node(NodeBase *pParent, const NameType &pName, TArgs &&... args)
Node(const Node &)=delete
Deleted copy constructor.
T data
The templated custom data object stored with each node.
Node(const NodeKey &pKey, TArgs &&... args)
cmTree * tree
The StringTree this object refers to.
ATMP_IF_T_F(!TConst, Node, const Node) cmNode
Constant or mutable version of type Node, depending on template parameter TConst
cmNode * followPath(SubstringType &path) const
TCursorBase(const TCursorBase &) noexcept=default
Trivial default copy constructor.
ATMP_IF_T_F(!TConst, NodeBase, const NodeBase) cmNodeBase
Constant or mutable version of type NodeBase, depending on template parameter TConst
TCursorBase() noexcept
Default constructor. Creates an invalid (uninitialized) object.
ATMP_IF_T_F(!TConst, StringTreeBase, const StringTreeBase) cmTree
Constant or mutable version of the base tree type, depending on template parameter TConst
TCursorBase(cmTree *pTree, cmNode *pNode) noexcept
TCursorBase(TCursorBase &&) noexcept=default
Trivial default move constructor.
std::pair< cmNode *, integer > followPathCreate(const NameType &path, TArgs &&... args)
cmNode * node
The currently represented node of the tree.
typename TNodeHandler::CharacterType CharacterType
StringTreeBase(TAllocator &allocator, TSharedRecycler &pRecycler, CharacterType pathSeparator)
StringTreeBase(TSharedRecycler &pRecycler, CharacterType pathSeparator)
bool checkChildName(const NameType &name) const
typename TNodeHandler::NameStringType NameStorageType
RootNodeSpacer root
The root node.
HashTable< TAllocator, typename NodeKey::ValueDescriptor, typename NodeKey::Hash, typename NodeKey::EqualTo, lang::Caching::Enabled, TRecycling > nodeTable
typename decltype(nodeTable)::SharedRecyclerType SharedRecyclerType
StringTreeBase(TAllocator &allocator, CharacterType pathSeparator)
typename strings::TSubstring< CharacterType > SubstringType
TAllocator & GetAllocator() noexcept
void reset() noexcept
Resets this list to zero elements.
TElement * first() const noexcept
void pushEnd(TElement *elem) noexcept
bool isEmpty() const noexcept
TNode hook
The root node. Points twice to itself when the list is empty.
void remove() noexcept
Unhooks this node from a list.
void next(SidiNodeBase *p)
NameType key
The name to compare when just keys are used.
NodeNameUnion(const NodeNameUnion &n)
Copy constructor.
NodeNameUnion(const NameType &n)
Constructor taking a key string.
NameStorageType storage
The name when stored in the hashtable.
~NodeNameUnion()
Destructor.
RootNodeSpacer()
Explicitly implement otherwise implicitly deleted constructor.
NodeBase rootBase
Base version of the root node, which becomes initialized.
Node root
Full version of the root node, without initialization of member T.
~RootNodeSpacer()
Destructor.