📄 structure.cpp
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........: 960307
// Description...:
// Revisions.....:
//===================================================================
#include <stdafx.h> // Precompiled headers.
#include <copyright.h>
#include <kernel/structures/structure.h>
#include <kernel/structures/projectmanager.h>
#include <kernel/algorithms/algorithm.h>
//-------------------------------------------------------------------
// Static methods (file scope).
//===================================================================
//-------------------------------------------------------------------
// Method ......: StaticRecursiveGetAllChildren
// Author........: Aleksander 豩rn/Daniel Remmem
// Date..........:
// Description...: Made static so as to hide the last recursion parameter
// for clients of GetAllChildren method.
// Comments......:
// Revisions.....:
//===================================================================
static bool
StaticRecursiveGetAllChildren(Id id, Identifier::Handles &children, const Structure *parent) {
// Valid parent?
if (parent == NULL)
return false;
int i;
// Loop recursively over all children.
for (i = 0; i < parent->GetNoChildren(); i++) {
Handle<Structure> child = parent->GetChild(i);
if (child->IsA(id))
children.push_back(Handle<Identifier>(child.GetPointer()));
if (!child->HasChildren())
continue;
if (!StaticRecursiveGetAllChildren(id, children, child.GetPointer()))
return false;
}
return true;
}
//-------------------------------------------------------------------
// Method........: StaticRecursiveFindParent
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Called from FindParent, used to hide recursion.
//
// Given two structures, whereof one is a descendant
// of the other, returns the descendant's immediate
// parent. If the descendant appears as an internal
// member structure of a structure set, the structure
// set is returned. If the descendant appears as a
// direct child of a parent structure, the parent
// structure is returned. Otherwise, NULL is returned.
//
// Comments......: Note that traversal of internal member structures is
// not implemented, although it really should be.
// This may not be fatal however, since usually internal
// member structures are "simple" in the sense that they
// aren't parent structures themselves.
// Revisions.....:
//===================================================================
static Structure *
StaticRecursiveFindParent(const Structure *descendant, const Structure *ancestor) {
// Check aregument validity.
if (descendant == NULL || ancestor == NULL)
return NULL;
// Check if the descendant is an internal member of the ancestor.
if (ancestor->IsMember(descendant))
return const_cast(Structure *, ancestor);
int i, no_children = ancestor->GetNoChildren();
// Iterate over all the ancestor's children.
for (i = 0; i < no_children; i++) {
// Get current child.
Structure *child = ancestor->GetChild(i);
// Is the current child and the descendant the same object?
if (child == descendant)
return const_cast(Structure *, ancestor);
// Is the descendant an internal member of the current child?
if (child->IsMember(descendant))
return child;
// Recurse.
child = StaticRecursiveFindParent(descendant, child);
// If the recursion was successful, return.
if (child != NULL)
return child;
}
// The structure is not a registered descendant of the given ancestor.
return NULL;
}
//-------------------------------------------------------------------
// Methods for class Structure.
//===================================================================
//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================
Structure::Structure(const Structure &/*in*/) {
}
Structure::Structure() {
}
Structure::~Structure() {
}
//-------------------------------------------------------------------
// Methods inherited from Identifier.
//===================================================================
IMPLEMENTIDMETHODS(Structure, STRUCTURE, Persistent)
//-------------------------------------------------------------------
// Methods inherited from Persistent.
//===================================================================
//-------------------------------------------------------------------
// Method........: Load
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Structure::Load(ifstream &stream) {
return Persistent::Load(stream);
}
//-------------------------------------------------------------------
// Method........: Save
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Structure::Save(ofstream &stream) const {
return Persistent::Save(stream);
}
//-------------------------------------------------------------------
// Method........: Load
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Structure::Load(const String &filename) {
return Persistent::Load(filename);
}
//-------------------------------------------------------------------
// Method........: Save
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Structure::Save(const String &filename) const {
return Persistent::Save(filename);
}
//-------------------------------------------------------------------
// New methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: Apply
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
Structure *
Structure::Apply(const Algorithm &algorithm) {
return algorithm.Apply(*this);
}
//-------------------------------------------------------------------
// Name management methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: GetName/SetName
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Makes the interface more uniform for structures
// with or without annotations.
//
// Should be overloaded by annotated structures.
// Revisions.....:
//===================================================================
const String &
Structure::GetName() const {
return IdHolder::GetClassname(GetId());
}
bool
Structure::SetName(const String &/*name*/) {
return false;
}
//-------------------------------------------------------------------
// Child management methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: GetNoChildren
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Makes the interface more uniform for structures
// with or without children.
//
// Should be overloaded by structures with children
// (parent structures).
// Revisions.....:
//===================================================================
int
Structure::GetNoChildren() const {
return 0;
}
//-------------------------------------------------------------------
// Method........: GetChild
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Makes the interface more uniform for structures with
// or without children.
//
// Should be overloaded by structures with children
// (parent structures).
// Revisions.....:
//===================================================================
Structure *
Structure::GetChild(int /*i*/) const {
Message::Error("This method should never have been invoked.");
return NULL;
}
//-------------------------------------------------------------------
// Method........: InsertChild
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Makes the interface more uniform for structures with
// or without children.
//
// Should be overloaded by structures with children
// (parent structures).
// Revisions.....:
//===================================================================
bool
Structure::InsertChild(Structure * /*child*/, int /*i*/) {
return false;
}
//-------------------------------------------------------------------
// Method........: AppendChild
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Makes the interface more uniform for structures with
// or without children.
// Revisions.....:
//===================================================================
bool
Structure::AppendChild(Structure *child) {
return InsertChild(child, GetNoChildren());
}
//-------------------------------------------------------------------
// Method........: RemoveChild
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Makes the interface more uniform for structures with
// or without children.
//
// Should be overloaded by structures with children
// (parent structures).
// Revisions.....:
//===================================================================
bool
Structure::RemoveChild(int /*i*/) {
return false;
}
//-------------------------------------------------------------------
// Method........: RemoveAllChildren
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Removes all children.
// Comments......:
// Revisions.....:
//===================================================================
bool
Structure::RemoveAllChildren() {
int i, no_children = GetNoChildren();
for (i = no_children - 1; i >= 0; i--) {
if (!RemoveChild(i))
return false;
}
return true;
}
//-------------------------------------------------------------------
// Method........: GetAllChildren
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in place) an array of pointers (handles)
// to all children of a specified type.
// Comments......:
// Revisions.....:
//===================================================================
bool
Structure::GetAllChildren(Id id, Identifier::Handles &children, bool recursive) const {
if (recursive)
return StaticRecursiveGetAllChildren(id, children, this);
int i;
// Loop over all immediate children.
for (i = 0; i < GetNoChildren(); i++) {
Handle<Structure> child = GetChild(i);
if (child->IsA(id))
children.push_back(Handle<Identifier>(child.GetPointer()));
}
return true;
}
//-------------------------------------------------------------------
// Method........: FindChild
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns the child index of the argument structure,
// Undefined::Integer() if not found.
//
// Comments......: Physical (not logical) check.
// Revisions.....:
//===================================================================
int
Structure::FindChild(const Structure *child) const {
int i, no_children = GetNoChildren();
for (i = 0; i < no_children; i++) {
if (child == GetChild(i))
return i;
}
return Undefined::Integer();
}
//-------------------------------------------------------------------
// Method........: IsParent
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns true if this structure is a parent of the
// argument structure. If the query is recursive,
// parenthood is generalized to being an ancestor.
// Comments......:
// Revisions.....:
//===================================================================
bool
Structure::IsParent(const Structure *child, bool recursive) const {
// Check immediate children.
if (FindChild(child) != Undefined::Integer())
return true;
if (!recursive)
return false;
int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -