347 lines
9.7 KiB
C++
347 lines
9.7 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#ifndef ARY_SYMTREE_NODE_HXX
|
|
#define ARY_SYMTREE_NODE_HXX
|
|
|
|
|
|
// USED SERVICES
|
|
// BASE CLASSES
|
|
// OTHER
|
|
|
|
|
|
|
|
namespace ary
|
|
{
|
|
namespace symtree
|
|
{
|
|
|
|
|
|
|
|
/** Represents a node in a tree of symbols like a namespace tree or a
|
|
directory tree.
|
|
|
|
@tpl NODE_TRAITS
|
|
Needs to define the types:
|
|
entity_base_type: The type of the entities in that storage,
|
|
e.g. ->ary::cpp::CodeEntity.
|
|
id_type: The type of the ids of those entities,
|
|
e.g. ->ary::cpp::Ce_id.
|
|
|
|
Needs to define the functions:
|
|
1. static entity_base_type &
|
|
EntityOf_(
|
|
id_type i_id );
|
|
2. static symtree::Node<LeNode_Traits> *
|
|
NodeOf_(
|
|
const entity_base_type &
|
|
i_entity );
|
|
3. static const String &
|
|
LocalNameOf_(
|
|
const entity_base_type &
|
|
i_entity );
|
|
4. static entity_base_type *
|
|
ParentOf_(
|
|
const entity_base_type &
|
|
i_entity );
|
|
5. template <class KEY>
|
|
static id_t Search_(
|
|
const entity_base_type &
|
|
i_entity,
|
|
const KEY & i_localKey );
|
|
*/
|
|
template <class NODE_TRAITS>
|
|
class Node
|
|
{
|
|
public:
|
|
typedef Node<NODE_TRAITS> node_self;
|
|
typedef typename NODE_TRAITS::entity_base_type entity_t;
|
|
typedef typename NODE_TRAITS::id_type id_t;
|
|
|
|
|
|
// LIFECYCLE
|
|
/// @attention Always needs to be followed by ->Assign_Entity()!
|
|
Node();
|
|
explicit Node(
|
|
entity_t & i_entity );
|
|
void Assign_Entity(
|
|
entity_t & i_entity );
|
|
~Node();
|
|
// INQUIRY
|
|
id_t Id();
|
|
const String Name() const;
|
|
int Depth() const;
|
|
const entity_t & Entity() const;
|
|
const node_self * Parent() const;
|
|
|
|
/** Gets a child with a specific name and of a specific type.
|
|
|
|
There may be more childs with the same name.
|
|
|
|
@return id_t(0), if no matching child is found.
|
|
*/
|
|
template <class KEY>
|
|
typename NODE_TRAITS::id_type
|
|
Search(
|
|
const KEY & i_localKey ) const
|
|
{
|
|
// Inline here to workaround SUNW8 compiler bug, works in SUNW12.
|
|
return NODE_TRAITS::Search_(Entity(), i_localKey);
|
|
}
|
|
|
|
|
|
/** Gets a child with a specific qualified name below this node.
|
|
|
|
The child may not exists.
|
|
*/
|
|
template <class KEY>
|
|
void SearchBelow(
|
|
id_t & o_return, // Workaround SUNW8 compiler bug
|
|
StringVector::const_iterator
|
|
i_qualifiedSearchedName_begin,
|
|
StringVector::const_iterator
|
|
i_qualifiedSearchedName_end,
|
|
const KEY & i_localKey ) const;
|
|
|
|
/** Gets a child with a specific qualified name, either below this node
|
|
or below any of the parent nodes.
|
|
|
|
The child may not exists.
|
|
*/
|
|
template <class KEY>
|
|
void SearchUp(
|
|
id_t & o_return, // Workaround SUNW8 compiler bug
|
|
StringVector::const_iterator
|
|
i_qualifiedSearchedName_begin,
|
|
StringVector::const_iterator
|
|
i_qualifiedSearchedName_end,
|
|
const KEY & i_localKey ) const;
|
|
// ACCESS
|
|
entity_t & Entity();
|
|
node_self * Parent();
|
|
|
|
private:
|
|
// Forbid copying:
|
|
Node(const node_self&);
|
|
node_self& operator=(const node_self&);
|
|
|
|
// Locals
|
|
void InitDepth();
|
|
node_self * Get_Parent() const;
|
|
node_self * NodeOf(
|
|
id_t i_id ) const;
|
|
|
|
// DATA
|
|
entity_t * pEntity;
|
|
int nDepth;
|
|
};
|
|
|
|
|
|
|
|
|
|
// IMPLEMENTATION
|
|
|
|
template <class NODE_TRAITS>
|
|
inline const typename Node<NODE_TRAITS>::entity_t &
|
|
Node<NODE_TRAITS>::Entity() const
|
|
{
|
|
csv_assert(pEntity != 0);
|
|
return *pEntity;
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
inline Node<NODE_TRAITS> *
|
|
Node<NODE_TRAITS>::NodeOf(id_t i_id) const
|
|
{
|
|
if (i_id.IsValid())
|
|
return NODE_TRAITS::NodeOf_(NODE_TRAITS::EntityOf_(i_id));
|
|
return 0;
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
inline Node<NODE_TRAITS> *
|
|
Node<NODE_TRAITS>::Get_Parent() const
|
|
{
|
|
entity_t *
|
|
parent = NODE_TRAITS::ParentOf_(Entity());
|
|
if (parent != 0)
|
|
return NODE_TRAITS::NodeOf_(*parent);
|
|
return 0;
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
Node<NODE_TRAITS>::Node()
|
|
: pEntity(0),
|
|
nDepth(0)
|
|
{
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
Node<NODE_TRAITS>::Node(entity_t & i_entity)
|
|
: pEntity(&i_entity),
|
|
nDepth(0)
|
|
{
|
|
InitDepth();
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
void
|
|
Node<NODE_TRAITS>::Assign_Entity(entity_t & i_entity)
|
|
{
|
|
pEntity = &i_entity;
|
|
InitDepth();
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
Node<NODE_TRAITS>::~Node()
|
|
{
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
inline typename Node<NODE_TRAITS>::id_t
|
|
Node<NODE_TRAITS>::Id()
|
|
{
|
|
return NODE_TRAITS::IdOf(Entity());
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
inline const String
|
|
Node<NODE_TRAITS>::Name() const
|
|
{
|
|
return NODE_TRAITS::LocalNameOf_(Entity());
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
inline int
|
|
Node<NODE_TRAITS>::Depth() const
|
|
{
|
|
return nDepth;
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
inline const Node<NODE_TRAITS> *
|
|
Node<NODE_TRAITS>::Parent() const
|
|
{
|
|
return Get_Parent();
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
template <class KEY>
|
|
void
|
|
Node<NODE_TRAITS>::SearchBelow(
|
|
id_t & o_return, // Workaround SUNW8 compiler bug
|
|
StringVector::const_iterator i_qualifiedSearchedName_begin,
|
|
StringVector::const_iterator i_qualifiedSearchedName_end,
|
|
const KEY & i_localKey ) const
|
|
{
|
|
if (i_qualifiedSearchedName_begin != i_qualifiedSearchedName_end)
|
|
{
|
|
id_t
|
|
next = Search(*i_qualifiedSearchedName_begin);
|
|
if (next.IsValid())
|
|
{
|
|
const node_self *
|
|
subnode = NodeOf(next);
|
|
if (subnode != 0)
|
|
{
|
|
subnode->SearchBelow( o_return,
|
|
i_qualifiedSearchedName_begin+1,
|
|
i_qualifiedSearchedName_end ,
|
|
i_localKey );
|
|
return;
|
|
}
|
|
}
|
|
o_return = id_t(0);
|
|
return;
|
|
}
|
|
|
|
o_return = Search(i_localKey);
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
template <class KEY>
|
|
void
|
|
Node<NODE_TRAITS>::SearchUp(
|
|
id_t & o_return, // Workaround SUNW8 compiler bug
|
|
StringVector::const_iterator i_qualifiedSearchedName_begin,
|
|
StringVector::const_iterator i_qualifiedSearchedName_end,
|
|
const KEY & i_localKey ) const
|
|
{
|
|
SearchBelow( o_return,
|
|
i_qualifiedSearchedName_begin,
|
|
i_qualifiedSearchedName_end,
|
|
i_localKey );
|
|
if (o_return.IsValid())
|
|
return;
|
|
|
|
node_self *
|
|
parent = Get_Parent();
|
|
if (parent != 0)
|
|
{
|
|
parent->SearchUp( o_return,
|
|
i_qualifiedSearchedName_begin,
|
|
i_qualifiedSearchedName_end,
|
|
i_localKey );
|
|
}
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
typename Node<NODE_TRAITS>::entity_t &
|
|
Node<NODE_TRAITS>::Entity()
|
|
{
|
|
csv_assert(pEntity != 0);
|
|
return *pEntity;
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
inline Node<NODE_TRAITS> *
|
|
Node<NODE_TRAITS>::Parent()
|
|
{
|
|
return Get_Parent();
|
|
}
|
|
|
|
template <class NODE_TRAITS>
|
|
void
|
|
Node<NODE_TRAITS>::InitDepth()
|
|
{
|
|
Node<NODE_TRAITS> *
|
|
pp = Get_Parent();
|
|
if (pp != 0)
|
|
nDepth = pp->Depth() + 1;
|
|
else
|
|
nDepth = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace symtree
|
|
} // namespace ary
|
|
#endif
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|