summaryrefslogtreecommitdiffstats
path: root/src/conceptdef.cpp
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2021-04-08 19:18:07 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2021-04-08 19:23:43 (GMT)
commite03e2a29f9279deabe62d795b0db925a982d0eef (patch)
tree8e0254cd7ea40d93489037f53d6f42d1619358c6 /src/conceptdef.cpp
parenta9e4a9e5b51ab33df64f3989c710e08546dcd45d (diff)
downloadDoxygen-e03e2a29f9279deabe62d795b0db925a982d0eef.zip
Doxygen-e03e2a29f9279deabe62d795b0db925a982d0eef.tar.gz
Doxygen-e03e2a29f9279deabe62d795b0db925a982d0eef.tar.bz2
issue #2732: Adding support for C++ concepts (Origin: bugzilla #499352)
Diffstat (limited to 'src/conceptdef.cpp')
-rw-r--r--src/conceptdef.cpp733
1 files changed, 733 insertions, 0 deletions
diff --git a/src/conceptdef.cpp b/src/conceptdef.cpp
new file mode 100644
index 0000000..c92237f
--- /dev/null
+++ b/src/conceptdef.cpp
@@ -0,0 +1,733 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2021 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "conceptdef.h"
+#include "definitionimpl.h"
+#include "util.h"
+#include "config.h"
+#include "doxygen.h"
+#include "language.h"
+#include "outputlist.h"
+#include "searchindex.h"
+#include "message.h"
+#include "parserintf.h"
+
+//------------------------------------------------------------------------------------
+
+class ConceptDefImpl : public DefinitionMixin<ConceptDefMutable>
+{
+ public:
+ ConceptDefImpl(const char *fileName,int startLine,int startColumn,
+ const char *name,const char *tagRef=0,const char *tagFile=0);
+ ~ConceptDefImpl();
+
+ virtual ConceptDef *resolveAlias() { return this; }
+
+ //---------- ConceptDef
+ virtual DefType definitionType() const;
+ virtual QCString getOutputFileBase() const;
+ virtual bool hasDetailedDescription() const;
+ virtual QCString displayName(bool includeScope=true) const;
+ virtual const IncludeInfo *includeInfo() const;
+ virtual ArgumentList getTemplateParameterList() const;
+ virtual QCString anchor() const;
+ virtual bool isLinkableInProject() const;
+ virtual bool isLinkable() const;
+ virtual QCString initializer() const;
+ virtual void writeDeclarationLink(OutputList &ol,bool &found,
+ const char *header,bool localNames) const;
+ virtual const NamespaceDef *getNamespaceDef() const;
+ virtual const FileDef *getFileDef() const;
+
+ //---------- ConceptDefMutable
+ virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force);
+ virtual void setTemplateArguments(const ArgumentList &al);
+ virtual void setNamespace(NamespaceDef *nd);
+ virtual void setFileDef(FileDef *fd);
+ virtual void writeTagFile(TextStream &);
+ virtual void writeDocumentation(OutputList &);
+ virtual void setInitializer(const char *init);
+ virtual void findSectionsInDocumentation();
+
+ //---------- Helpers
+ void writeBriefDescription(OutputList &) const;
+ void writeAuthorSection(OutputList &ol) const;
+ void writeIncludeFiles(OutputList &ol) const;
+ void writeDetailedDescription(OutputList &ol,const QCString &title) const;
+ void writeDefinition(OutputList &ol,const QCString &title) const;
+
+ private:
+ QCString m_fileName;
+ std::unique_ptr<IncludeInfo> m_incInfo;
+ NamespaceDef *m_nspace = 0;
+ FileDef *m_fileDef = 0;
+ ArgumentList m_tArgList;
+ QCString m_initializer;
+};
+
+ConceptDefMutable *createConceptDef(
+ const char *fileName,int startLine,int startColumn,
+ const char *name, const char *tagRef,const char *tagFile)
+{
+ return new ConceptDefImpl(fileName,startLine,startColumn,name,tagRef,tagFile);
+}
+
+//------------------------------------------------------------------------------------
+
+class ConceptDefAliasImpl : public DefinitionAliasMixin<ConceptDef>
+{
+ public:
+ ConceptDefAliasImpl(const Definition *newScope,const ConceptDef *cd)
+ : DefinitionAliasMixin(newScope,cd) { init(); }
+ virtual ~ConceptDefAliasImpl() { deinit(); }
+
+ const ConceptDef *getCdAlias() const { return toConceptDef(getAlias()); }
+ virtual ConceptDef *resolveAlias() { return const_cast<ConceptDef*>(getCdAlias()); }
+
+ virtual DefType definitionType() const { return TypeConcept; }
+ virtual QCString getOutputFileBase() const
+ { return getCdAlias()->getOutputFileBase(); }
+ virtual QCString getReference() const
+ { return getCdAlias()->getReference(); }
+ virtual bool isReference() const
+ { return getCdAlias()->isReference(); }
+ virtual bool hasDetailedDescription() const
+ { return getCdAlias()->hasDetailedDescription(); }
+ virtual QCString displayName(bool includeScope=true) const
+ { return getCdAlias()->displayName(includeScope); }
+ virtual const IncludeInfo *includeInfo() const
+ { return getCdAlias()->includeInfo(); }
+ virtual ArgumentList getTemplateParameterList() const
+ { return getCdAlias()->getTemplateParameterList(); }
+ virtual QCString anchor() const
+ { return getCdAlias()->anchor(); }
+ virtual bool isLinkableInProject() const
+ { return getCdAlias()->isLinkableInProject(); }
+ virtual bool isLinkable() const
+ { return getCdAlias()->isLinkable(); }
+ virtual QCString initializer() const
+ { return getCdAlias()->initializer(); }
+ virtual const NamespaceDef *getNamespaceDef() const
+ { return getCdAlias()->getNamespaceDef(); }
+ virtual const FileDef *getFileDef() const
+ { return getCdAlias()->getFileDef(); }
+ virtual void writeDeclarationLink(OutputList &ol,bool &found,
+ const char *header,bool localNames) const
+ { getCdAlias()->writeDeclarationLink(ol,found,header,localNames); }
+};
+
+ConceptDef *createConceptDefAlias(const Definition *newScope,const ConceptDef *cd)
+{
+ ConceptDef *acd = new ConceptDefAliasImpl(newScope,cd);
+ return acd;
+}
+
+//------------------------------------------------------------------------------------
+
+ConceptDefImpl::ConceptDefImpl(const char *fileName,int startLine,int startColumn,
+ const char *name,const char *tagRef,const char *tagFile) : DefinitionMixin(fileName,startLine,startColumn,name)
+{
+ if (tagFile)
+ {
+ if (tagRef)
+ {
+ m_fileName = stripExtension(tagFile);
+ }
+ else
+ {
+ m_fileName = convertNameToFile(stripExtension(tagFile));
+ }
+ }
+ else
+ {
+ m_fileName = convertNameToFile(QCString("concept")+name);
+ }
+ setReference(tagRef);
+}
+
+ConceptDefImpl::~ConceptDefImpl()
+{
+}
+
+Definition::DefType ConceptDefImpl::definitionType() const
+{
+ return TypeConcept;
+}
+
+QCString ConceptDefImpl::getOutputFileBase() const
+{
+ return m_fileName;
+}
+
+bool ConceptDefImpl::hasDetailedDescription() const
+{
+ bool repeatBrief = Config_getBool(REPEAT_BRIEF);
+ bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
+ return ((!briefDescription().isEmpty() && repeatBrief) ||
+ !documentation().isEmpty() ||
+ (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()));
+}
+
+QCString ConceptDefImpl::anchor() const
+{
+ return "";
+}
+
+QCString ConceptDefImpl::displayName(bool includeScope) const
+{
+ return includeScope ? name() : localName();
+}
+
+const IncludeInfo *ConceptDefImpl::includeInfo() const
+{
+ return m_incInfo.get();
+}
+
+ArgumentList ConceptDefImpl::getTemplateParameterList() const
+{
+ return m_tArgList;
+}
+
+bool ConceptDefImpl::isLinkableInProject() const
+{
+ return hasDocumentation() && !isReference() && !isHidden();
+}
+
+bool ConceptDefImpl::isLinkable() const
+{
+ return isLinkableInProject() || isReference();
+}
+
+void ConceptDefImpl::setIncludeFile(FileDef *fd,const char *incName,bool local,bool force)
+{
+ if (!m_incInfo) m_incInfo = std::make_unique<IncludeInfo>();
+ if ((incName && m_incInfo->includeName.isEmpty()) ||
+ (fd!=0 && m_incInfo->fileDef==0)
+ )
+ {
+ m_incInfo->fileDef = fd;
+ m_incInfo->includeName = incName;
+ m_incInfo->local = local;
+ }
+ if (force && incName)
+ {
+ m_incInfo->includeName = incName;
+ m_incInfo->local = local;
+ }
+}
+
+void ConceptDefImpl::setTemplateArguments(const ArgumentList &al)
+{
+ m_tArgList = al;
+}
+
+void ConceptDefImpl::setNamespace(NamespaceDef *nd)
+{
+ m_nspace = nd;
+}
+
+const NamespaceDef *ConceptDefImpl::getNamespaceDef() const
+{
+ return m_nspace;
+}
+
+void ConceptDefImpl::setFileDef(FileDef *fd)
+{
+ m_fileDef=fd;
+}
+
+const FileDef *ConceptDefImpl::getFileDef() const
+{
+ return m_fileDef;
+}
+
+void ConceptDefImpl::setInitializer(const char *init)
+{
+ m_initializer = init;
+}
+
+QCString ConceptDefImpl::initializer() const
+{
+ return m_initializer;
+}
+
+void ConceptDefImpl::writeTagFile(TextStream &tagFile)
+{
+ tagFile << " <compound kind=\"concept\">\n";
+ tagFile << " <name>" << convertToXML(name()) << "</name>\n";
+ tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>\n";
+ QCString idStr = id();
+ if (!idStr.isEmpty())
+ {
+ tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
+ }
+ writeDocAnchorsToTagFile(tagFile);
+ tagFile << " </compound>\n";
+}
+
+void ConceptDefImpl::writeBriefDescription(OutputList &ol) const
+{
+ if (hasBriefDescription())
+ {
+ DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startParagraph();
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.writeString(" - ");
+ ol.popGeneratorState();
+ ol.writeDoc(rootNode,this,0);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
+
+ if (hasDetailedDescription())
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startTextLink(getOutputFileBase(),"details");
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ }
+ ol.popGeneratorState();
+ ol.endParagraph();
+ }
+ delete rootNode;
+ }
+ ol.writeSynopsis();
+}
+
+void ConceptDefImpl::writeIncludeFiles(OutputList &ol) const
+{
+ if (m_incInfo)
+ {
+ QCString nm=m_incInfo->includeName.isEmpty() ?
+ (m_incInfo->fileDef ?
+ m_incInfo->fileDef->docName().data() : ""
+ ) :
+ m_incInfo->includeName.data();
+ if (!nm.isEmpty())
+ {
+ ol.startParagraph();
+ ol.startTypewriter();
+ ol.docify("#include ");
+ if (m_incInfo->local)
+ ol.docify("\"");
+ else
+ ol.docify("<");
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.docify(nm);
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.enable(OutputGenerator::Html);
+ if (m_incInfo->fileDef)
+ {
+ ol.writeObjectLink(0,m_incInfo->fileDef->includeName(),0,nm);
+ }
+ else
+ {
+ ol.docify(nm);
+ }
+ ol.popGeneratorState();
+ if (m_incInfo->local)
+ ol.docify("\"");
+ else
+ ol.docify(">");
+ ol.endTypewriter();
+ ol.endParagraph();
+ }
+ }
+}
+
+static QCString templateSpec(const ArgumentList &al)
+{
+ TextStream t;
+ t << "template<";
+ bool first=true;
+ for (const auto &a : al)
+ {
+ if (!first) t << ", ";
+ t << a.type;
+ if (!a.name.isEmpty())
+ {
+ t << " " << a.name;
+ }
+ if (a.defval.length()!=0)
+ {
+ t << " " << a.defval;
+ }
+ first=false;
+ }
+ t << ">";
+ return t.str();
+}
+
+void ConceptDefImpl::writeDefinition(OutputList &ol,const QCString &title) const
+{
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+
+ auto intf = Doxygen::parserManager->getCodeParser(".cpp");
+ intf->resetCodeParserState();
+ ol.startCodeFragment("DoxyCode");
+ QCString scopeName;
+ if (getOuterScope()!=Doxygen::globalScope) scopeName=getOuterScope()->name();
+ TextStream conceptDef;
+ conceptDef << templateSpec(m_tArgList);
+ conceptDef << "\nconcept ";
+ conceptDef << name();
+ conceptDef << " = ";
+ conceptDef << m_initializer;
+ intf->parseCode(ol,scopeName,conceptDef.str(),SrcLangExt_Cpp,false,0,
+ m_fileDef, -1,-1,true,0,false,this);
+ ol.endCodeFragment("DoxyCode");
+}
+
+void ConceptDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) const
+{
+ static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
+ if (hasDetailedDescription())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeAnchor(0,"details");
+ ol.popGeneratorState();
+
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+
+ ol.startTextBlock();
+ // repeat brief description
+ if (!briefDescription().isEmpty() && repeatBrief)
+ {
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
+ }
+ if (!briefDescription().isEmpty() && repeatBrief &&
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeString("\n\n");
+ ol.popGeneratorState();
+ }
+
+ // write documentation
+ if (!documentation().isEmpty())
+ {
+ ol.generateDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
+ }
+
+ writeSourceDef(ol,name());
+ ol.endTextBlock();
+ }
+}
+
+void ConceptDefImpl::writeAuthorSection(OutputList &ol) const
+{
+ // write Author section (Man only)
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.startGroupHeader();
+ ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
+ ol.endGroupHeader();
+ ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString(PROJECT_NAME)));
+ ol.popGeneratorState();
+}
+
+void ConceptDefImpl::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
+ QCString pageTitle = theTranslator->trConceptReference(displayName());
+ startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ConceptVisible,!generateTreeView);
+
+ // ---- navigation part
+ if (!generateTreeView)
+ {
+ if (getOuterScope()!=Doxygen::globalScope)
+ {
+ writeNavigationPath(ol);
+ }
+ ol.endQuickIndices();
+ }
+
+ // ---- title part
+ startTitle(ol,getOutputFileBase(),this);
+ ol.parseText(pageTitle);
+ endTitle(ol,getOutputFileBase(),displayName());
+
+ // ---- contents part
+
+ ol.startContents();
+
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
+ Doxygen::searchIndex->addWord(localName(),TRUE);
+ }
+
+ Doxygen::indexList->addIndexItem(this,0);
+ //---------------------------------------- start flexible part -------------------------------
+
+ for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Concept))
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ writeBriefDescription(ol);
+ break;
+ case LayoutDocEntry::ConceptDefinition:
+ {
+ const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get();
+ writeDefinition(ol,ls->title(getLanguage()));
+ }
+ break;
+ case LayoutDocEntry::DetailedDesc:
+ {
+ const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get();
+ writeDetailedDescription(ol,ls->title(getLanguage()));
+ }
+ break;
+ case LayoutDocEntry::AuthorSection:
+ writeAuthorSection(ol);
+ break;
+ case LayoutDocEntry::ClassIncludes:
+ writeIncludeFiles(ol);
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ case LayoutDocEntry::NamespaceClasses:
+ case LayoutDocEntry::NamespaceInterfaces:
+ case LayoutDocEntry::NamespaceStructs:
+ case LayoutDocEntry::NamespaceExceptions:
+ case LayoutDocEntry::NamespaceConcepts:
+ case LayoutDocEntry::NamespaceNestedNamespaces:
+ case LayoutDocEntry::NamespaceNestedConstantGroups:
+ case LayoutDocEntry::MemberGroups:
+ case LayoutDocEntry::MemberDecl:
+ case LayoutDocEntry::MemberDeclEnd:
+ case LayoutDocEntry::MemberDefStart:
+ case LayoutDocEntry::NamespaceInlineClasses:
+ case LayoutDocEntry::MemberDef:
+ case LayoutDocEntry::MemberDefEnd:
+ case LayoutDocEntry::ClassInheritanceGraph:
+ case LayoutDocEntry::ClassNestedClasses:
+ case LayoutDocEntry::ClassCollaborationGraph:
+ case LayoutDocEntry::ClassAllMembersLink:
+ case LayoutDocEntry::ClassUsedFiles:
+ case LayoutDocEntry::ClassInlineClasses:
+ case LayoutDocEntry::FileClasses:
+ case LayoutDocEntry::FileConcepts:
+ case LayoutDocEntry::FileInterfaces:
+ case LayoutDocEntry::FileStructs:
+ case LayoutDocEntry::FileExceptions:
+ case LayoutDocEntry::FileNamespaces:
+ case LayoutDocEntry::FileConstantGroups:
+ case LayoutDocEntry::FileIncludes:
+ case LayoutDocEntry::FileIncludeGraph:
+ case LayoutDocEntry::FileIncludedByGraph:
+ case LayoutDocEntry::FileInlineClasses:
+ case LayoutDocEntry::FileSourceLink:
+ case LayoutDocEntry::GroupClasses:
+ case LayoutDocEntry::GroupConcepts:
+ case LayoutDocEntry::GroupInlineClasses:
+ case LayoutDocEntry::GroupNamespaces:
+ case LayoutDocEntry::GroupDirs:
+ case LayoutDocEntry::GroupNestedGroups:
+ case LayoutDocEntry::GroupFiles:
+ case LayoutDocEntry::GroupGraph:
+ case LayoutDocEntry::GroupPageDocs:
+ case LayoutDocEntry::DirSubDirs:
+ case LayoutDocEntry::DirFiles:
+ case LayoutDocEntry::DirGraph:
+ err("Internal inconsistency: member %d should not be part of "
+ "LayoutDocManager::Namespace entry list\n",lde->kind());
+ break;
+ }
+ }
+
+ //---------------------------------------- end flexible part -------------------------------
+
+ ol.endContents();
+
+ endFileWithNavPath(this,ol);
+}
+
+void ConceptDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames) const
+{
+ if (isLinkable())
+ {
+ if (!found) // first concept
+ {
+ ol.startMemberHeader("concepts");
+ if (header)
+ {
+ ol.parseText(header);
+ }
+ else
+ {
+ theTranslator->trConcept(true,false);
+ }
+ ol.endMemberHeader();
+ ol.startMemberList();
+ found=TRUE;
+ }
+ ol.startMemberDeclaration();
+ ol.startMemberItem(anchor(),FALSE);
+ ol.writeString("concept ");
+ QCString cname = displayName(!localNames);
+ ol.insertMemberAlign();
+ if (isLinkable())
+ {
+ ol.writeObjectLink(getReference(),
+ getOutputFileBase(),
+ anchor(),
+ cname
+ );
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(cname);
+ ol.endBold();
+ }
+ ol.endMemberItem();
+ // add the brief description if available
+ if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
+ {
+ DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
+ if (rootNode && !rootNode->isEmpty())
+ {
+ ol.startMemberDescription(anchor());
+ ol.writeDoc(rootNode,this,0);
+ ol.endMemberDescription();
+ }
+ delete rootNode;
+ }
+ ol.endMemberDeclaration(anchor(),0);
+ }
+}
+
+void ConceptDefImpl::findSectionsInDocumentation()
+{
+ docFindSections(briefDescription(),this,docFile());
+ docFindSections(documentation(),this,docFile());
+}
+
+//------------------------------------------------------------------------------------
+
+bool ConceptLinkedRefMap::declVisible() const
+{
+ bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
+ for (const auto &cd : *this)
+ {
+ bool isLink = cd->isLinkable();
+ if (isLink || !hideUndocClasses)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ConceptLinkedRefMap::writeDeclaration(OutputList &ol,const char *header,bool localNames) const
+{
+ bool found=FALSE;
+ for (const auto &cd : *this)
+ {
+ cd->writeDeclarationLink(ol,found,header,localNames);
+ }
+ if (found) ol.endMemberList();
+}
+
+//------------------------------------------------------------------------------------
+
+// --- Cast functions
+//
+ConceptDef *toConceptDef(Definition *d)
+{
+ if (d && (typeid(*d)==typeid(ConceptDefImpl) || typeid(*d)==typeid(ConceptDefAliasImpl)))
+ {
+ return static_cast<ConceptDef*>(d);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+ConceptDef *toConceptDef(DefinitionMutable *md)
+{
+ Definition *d = toDefinition(md);
+ if (d && typeid(*d)==typeid(ConceptDefImpl))
+ {
+ return static_cast<ConceptDef*>(d);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+const ConceptDef *toConceptDef(const Definition *d)
+{
+ if (d && (typeid(*d)==typeid(ConceptDefImpl) || typeid(*d)==typeid(ConceptDefAliasImpl)))
+ {
+ return static_cast<const ConceptDef*>(d);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+ConceptDefMutable *toConceptDefMutable(Definition *d)
+{
+ if (d && typeid(*d)==typeid(ConceptDefImpl))
+ {
+ return static_cast<ConceptDefMutable*>(d);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+ConceptDefMutable *toConceptDefMutable(const Definition *d)
+{
+ if (d && typeid(*d)==typeid(ConceptDefImpl))
+ {
+ return const_cast<ConceptDefMutable*>(static_cast<const ConceptDefMutable*>(d));
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+