NameSpaceRegistry.h
// NameSpaceRegistry.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2008
@import "Object.h"
@import "SubString.h"
namespace ceda
{
$adt NameSpace;
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Namespace registries
--------------------
All the reflected interfaces, classes etc are registered in a namespace tree. Each namespace node
registers all items in the one map, keyed by string. This means that it is necessary for all items
to have unique names - even different types. This restriction is not conventional in C++ (which for
example, within the same namespace allows for a class to have the same name as a global variable).
This restriction is made in the interests of easing cross language support, such as with the Python
language.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
// ENSType
$enum+ ENSType
{
NST_Unknown,
@for (rType in mRegistryTypes)
{
NST_@@rType,
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// NameSpaceElement
$struct+ NameSpaceElement
{
// Define a default ctor so this type is not a POD, so dynamic invocation works correctly
// when a NameSpaceElement is a return type of a function
NameSpaceElement() { type = NST_Unknown; item = nullptr; }
~NameSpaceElement() { type = NST_Unknown; item = nullptr; }
$ENSType GetType() const { return type; }
@for (rType in mRegistryTypes)
{
@def R = Reflected@@rType
$const R* As@@rType() const
{
cxAssert(type == NST_@@rType);
return (const R*) item;
}
}
/////////////// State ////////////////////////
ENSType type;
const void* item;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// NameSpaceElementIterator
/*
Allows for iteration through all the elements in a namespace. Typically a client will write a
loop using the iterator as follows.
void Example(NameSpace* ns)
{
NameSpaceIterator* i = GetIterator(ns);
while(!AtEnd(i))
{
NameSpaceElement nse = GetElement(i);
SubString name = GetName(i);
< process nse >
Next(i);
}
Close(i);
}
It is important for the iterator to be closed (even if it is not actually used)
*/
$adt+ NameSpaceElementIterator
{
bool AtEnd() const;
void Next();
SubString GetName() const;
NameSpaceElement GetElement() const;
void Close();
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// ChildNameSpaceIterator
/*
Allows for iteration through all the child namespaces in a namespace.
*/
$adt+ ChildNameSpaceIterator
{
bool AtEnd() const;
void Next();
SubString GetName() const;
NameSpace* GetNameSpace() const;
void Close();
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// NameSpace
$adt+ NameSpace
{
ConstStringZ GetName() const;
// Look up an element with the given name
NameSpaceElement FindElement(SubString name) const;
// Look up element using a relative path. todo : do we search upwards?
// Possible return values :
// NSE_OK
// NSE_COLON_EXPECTED
// NSE_IDENTIFIER_EXPECTED
// NSE_NAME_NOT_FOUND
// NSE_NOT_A_NAMESPACE
ENameSpaceError FindElementWithRelativePath(SubString relativePath, NameSpaceElement& nse) const;
// Allow for iteration over all elements in this namespace. The returned iterator must be closed,
// regardless of whether it is used or not.
NameSpaceElementIterator* GetElementIterator() const;
// Look up a child namespace with the given name. Returns nullptr if not found.
NameSpace* FindChildNameSpace(SubString name) const;
ChildNameSpaceIterator* GetChildNameSpaceIterator() const;
};
$function+ NameSpace* GetTheRootNameSpace();
} // namespace ceda