summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-22 00:43:40 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-22 00:43:40 +0100
commit33008f1110523ae9c9b9e1d2ca24ed642637c40d (patch)
treed058340aaab51df5a59dc89a8b08b829923074b3 /src
parent601d07df6339696bace0f303a69a0a02a39f9eea (diff)
added move semantics do Domain and Document classes.
Diffstat (limited to 'src')
-rw-r--r--src/core/model/Document.cpp89
-rw-r--r--src/core/model/Document.hpp88
-rw-r--r--src/core/model/Domain.cpp101
-rw-r--r--src/core/model/Domain.hpp64
4 files changed, 282 insertions, 60 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp
index f29af1c..2ae9107 100644
--- a/src/core/model/Document.cpp
+++ b/src/core/model/Document.cpp
@@ -335,13 +335,39 @@ void DocumentEntity::setAttributes(const Variant &a)
void DocumentEntity::addStructureNode(Handle<StructureNode> s, const int &i)
{
- invalidateSubInstance();
- fields[i].push_back(s);
- if (s->getParent() != subInst) {
+ // only add the new node if we don't have it already.
+ auto it = fields[i].find(s);
+ if (it == fields[i].end()) {
+ invalidateSubInstance();
+ fields[i].push_back(s);
+ }
+ Handle<Managed> par = s->getParent();
+ if (par != subInst) {
+ // if a previous parent existed, remove the StructureNode from it
+ if (par != nullptr) {
+ if (par->isa(RttiTypes::StructuredEntity)) {
+ par.cast<StructuredEntity>()->removeStructureNode(s);
+ } else {
+ par.cast<AnnotationEntity>()->removeStructureNode(s);
+ }
+ }
s->setParent(subInst);
}
}
+bool DocumentEntity::removeStructureNodeFromField(Handle<StructureNode> s,
+ const int &i)
+{
+ auto it = fields[i].find(s);
+ if (it != fields[i].end()) {
+ invalidateSubInstance();
+ fields[i].erase(it);
+ s->setParent(nullptr);
+ return true;
+ }
+ return false;
+}
+
void DocumentEntity::addStructureNode(Handle<StructureNode> s,
const std::string &fieldName)
{
@@ -357,6 +383,13 @@ void DocumentEntity::addStructureNodes(
}
}
+bool DocumentEntity::removeStructureNodeFromField(
+ Handle<StructureNode> s, const std::string &fieldName)
+{
+ return removeStructureNodeFromField(
+ s, getFieldDescriptorIndex(fieldName, true));
+}
+
void DocumentEntity::addStructureNode(Handle<StructureNode> s,
Handle<FieldDescriptor> fieldDescriptor)
{
@@ -373,6 +406,28 @@ void DocumentEntity::addStructureNodes(
}
}
+bool DocumentEntity::removeStructureNodeFromField(
+ Handle<StructureNode> s, Handle<FieldDescriptor> fieldDescriptor)
+{
+ return removeStructureNodeFromField(
+ s, getFieldDescriptorIndex(fieldDescriptor, true));
+}
+
+bool DocumentEntity::removeStructureNode(Handle<StructureNode> s)
+{
+ for (auto field : fields) {
+ auto it = field.find(s);
+ if (it != field.end()) {
+ invalidateSubInstance();
+ field.erase(it);
+ s->setParent(nullptr);
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Class StructureNode */
bool StructureNode::doValidate(Logger &logger) const
@@ -558,9 +613,17 @@ bool Document::doValidate(Logger &logger) const
void Document::addAnnotation(Handle<AnnotationEntity> a)
{
- invalidate();
- annotations.push_back(a);
- if (a->getParent() != this) {
+ // only add it if we need to.
+ if (annotations.find(a) == annotations.end()) {
+ invalidate();
+ annotations.push_back(a);
+ }
+ Handle<Managed> par = a->getParent();
+ if (par != this) {
+ if (par != nullptr) {
+ // remove the StructuredClass from the old parent.
+ par.cast<Document>()->removeAnnotation(a);
+ }
a->setParent(this);
}
}
@@ -572,6 +635,20 @@ void Document::addAnnotations(const std::vector<Handle<AnnotationEntity>> &as)
}
}
+
+
+bool Document::removeAnnotation(Handle<AnnotationEntity> a)
+{
+ auto it = annotations.find(a);
+ if (it != annotations.end()) {
+ invalidate();
+ annotations.erase(it);
+ a->setParent(nullptr);
+ return true;
+ }
+ return false;
+}
+
bool Document::hasChild(Handle<StructureNode> s) const
{
Rooted<Managed> parent = s->getParent();
diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp
index f13faf2..7357dd2 100644
--- a/src/core/model/Document.hpp
+++ b/src/core/model/Document.hpp
@@ -162,6 +162,8 @@ private:
void addStructureNode(Handle<StructureNode> s, const int &i);
+ bool removeStructureNodeFromField(Handle<StructureNode> s, const int &i);
+
protected:
bool doValidate(Logger &logger) const;
@@ -278,8 +280,8 @@ public:
* If the name is unknown an exception is thrown.
*
* This method also changes the parent of the newly added StructureNode if
- * it is not set to this DocumentEntity already.
- * TODO: This could get move semantics.
+ * it is not set to this DocumentEntity already and removes it from the
+ * old parent.
*
* @param s is the StructureNode that shall be added.
* @param fieldName is the name of a field as specified in the
@@ -287,6 +289,7 @@ public:
*/
void addStructureNode(Handle<StructureNode> s,
const std::string &fieldName = "");
+
/**
* This adds multiple StructureNodes to the field with the given name.
* If an empty name is given it is assumed that the 'default'
@@ -297,7 +300,8 @@ public:
* If the name is unknown an exception is thrown.
*
* This method also changes the parent of each newly added StructureNode if
- * it is not set to this DocumentEntity already.
+ * it is not set to this DocumentEntity already and removes it from the
+ * old parent.
*
* @param ss are the StructureNodes that shall be added.
* @param fieldName is the name of a field as specified in the
@@ -307,13 +311,34 @@ public:
const std::string &fieldName = "");
/**
+ * This removes a StructureNode from the field with the given name. If an
+ * empty name is given it is assumed that the 'default' FieldDescriptor is
+ * referenced, where 'default' means either:
+ * 1.) The only TREE typed FieldDescriptor (if present) or
+ * 2.) the only FieldDescriptor (if only one is specified).
+ *
+ * If the name is unknown an exception is thrown.
+ *
+ * This method also changes the parent of the removed StructureNode to null.
+ *
+ * @param s is the StructureNode that shall be removed.
+ * @param fieldName is the name of a field as specified in the
+ * FieldDescriptor in the Domain description.
+ * @return true if this StructureNode was a child here and false if
+ * if was not found.
+ */
+ bool removeStructureNodeFromField(Handle<StructureNode> s,
+ const std::string &fieldName = "");
+
+ /**
* This adds a StructureNode to the field with the given FieldDescriptor.
*
* If the FieldDescriptor does not belong to the Descriptor of this node
* an exception is thrown.
*
* This method also changes the parent of the newly added StructureNode if
- * it is not set to this DocumentEntity already.
+ * it is not set to this DocumentEntity already and removes it from the
+ * old parent.
*
* @param s is the StructureNode that shall be added.
* @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for
@@ -330,7 +355,8 @@ public:
* an exception is thrown.
*
* This method also changes the parent of each newly added StructureNode if
- * it is not set to this DocumentEntity already.
+ * it is not set to this DocumentEntity already and removes it from the
+ * old parent.
*
* @param ss are the StructureNodes that shall be added.
* @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for
@@ -338,6 +364,35 @@ public:
*/
void addStructureNodes(const std::vector<Handle<StructureNode>> &ss,
Handle<FieldDescriptor> fieldDescriptor);
+
+ /**
+ * This removes a StructureNode from the field with the given
+ * FieldDescriptor.
+ *
+ * This method also changes the parent of the removed StructureNode to null.
+ *
+ * @param s is the StructureNode that shall be removed.
+ * @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for
+ * this DocumentEntity.
+
+ * @return true if this StructureNode was a child here and false if
+ * if was not found.
+ */
+ bool removeStructureNodeFromField(Handle<StructureNode> s,
+ Handle<FieldDescriptor> fieldDescriptor);
+
+ /**
+ * This removes a StructureNode from this DocumentEntity. It iterates
+ * through all fields to find it.
+ *
+ * This method also changes the parent of the removed StructureNode to null.
+ *
+ * @param s is the StructureNode that shall be removed.
+
+ * @return true if this StructureNode was a child here and false if if was
+ * not found.
+ */
+ bool removeStructureNode(Handle<StructureNode> s);
};
/**
@@ -680,21 +735,32 @@ public:
}
/**
- * Adds an AnnotationEntity to this document. This also sets the parent
- * of the given AnnotationEntity if it is not set to this document already.
+ * Adds an AnnotationEntity to this Document. This also sets the parent
+ * of the given AnnotationEntity if it is not set to this Document already
+ * and removes it from the old Document.
*
* @param a is some AnnotationEntity
*/
void addAnnotation(Handle<AnnotationEntity> a);
/**
- * Adds multiple AnnotationEntities to this document. This also sets the
- * parent of each given AnnotationEntity if it is not set to this document
- * already.
+ * Adds multiple AnnotationEntities to this Document. This also sets the
+ * parent of each given AnnotationEntity if it is not set to this Document
+ * already and removes it from the old Document.
*
* @param as is a vector of AnnotationEntities.
*/
- void addAnnotations(const std::vector<Handle<AnnotationEntity>>& as);
+ void addAnnotations(const std::vector<Handle<AnnotationEntity>> &as);
+
+ /**
+ * Removes an AnnotationEntity from this Document. This also sets the parent
+ * of the given AnnotationEntity to null.
+ *
+ * @param a is some AnnotationEntity.
+ * @return true if the given AnnotationEntity was removed and false if this
+ * Document did not have the given AnnotationEntity as child.
+ */
+ bool removeAnnotation(Handle<AnnotationEntity> a);
/**
* Returns a const reference to the NodeVector of Domains that are used
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index 50bde9c..b425174 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -59,7 +59,7 @@ bool FieldDescriptor::doValidate(Logger &logger) const
{
bool valid = true;
// check parent type
- if(getParent() == nullptr){
+ if (getParent() == nullptr) {
logger.error("This field has no parent!");
valid = false;
} else if (!getParent()->isa(RttiTypes::Descriptor)) {
@@ -110,10 +110,10 @@ bool FieldDescriptor::doValidate(Logger &logger) const
return valid;
}
-
-bool FieldDescriptor::removeChild(Handle<StructuredClass> c){
+bool FieldDescriptor::removeChild(Handle<StructuredClass> c)
+{
auto it = children.find(c);
- if(it != children.end()){
+ if (it != children.end()) {
invalidate();
children.erase(it);
return true;
@@ -138,7 +138,7 @@ bool Descriptor::doValidate(Logger &logger) const
{
bool valid = true;
// check parent type
- if(getParent() == nullptr){
+ if (getParent() == nullptr) {
logger.error("This Descriptor has no parent!");
valid = false;
} else if (!getParent()->isa(RttiTypes::Domain)) {
@@ -149,7 +149,7 @@ bool Descriptor::doValidate(Logger &logger) const
if (getName().empty()) {
logger.error("The name of this Descriptor is empty!");
valid = false;
- } else{
+ } else {
valid = valid & validateName(logger);
}
// check if all FieldDescriptors have this Descriptor as parent.
@@ -244,9 +244,25 @@ bool Descriptor::continuePath(Handle<StructuredClass> target,
return found;
}
+void Descriptor::addFieldDescriptor(Handle<FieldDescriptor> fd)
+{
+ // only add it if we need to.
+ if (fieldDescriptors.find(fd) == fieldDescriptors.end()) {
+ invalidate();
+ fieldDescriptors.push_back(fd);
+ }
+ Handle<Managed> par = fd->getParent();
+ if (par != this) {
+ if (par != nullptr) {
+ // remove the FieldDescriptor from the old parent.
+ par.cast<Descriptor>()->removeFieldDescriptor(fd);
+ }
+ fd->setParent(this);
+ }
+}
+
void Descriptor::copyFieldDescriptor(Handle<FieldDescriptor> fd)
{
- invalidate();
if (fd->getFieldType() == FieldDescriptor::FieldType::PRIMITIVE) {
/*
* To call the "new" operation is enough here, because the
@@ -261,6 +277,18 @@ void Descriptor::copyFieldDescriptor(Handle<FieldDescriptor> fd)
}
}
+bool Descriptor::removeFieldDescriptor(Handle<FieldDescriptor> fd)
+{
+ auto it = fieldDescriptors.find(fd);
+ if (it != fieldDescriptors.end()) {
+ invalidate();
+ fieldDescriptors.erase(it);
+ fd->setParent(nullptr);
+ return true;
+ }
+ return false;
+}
+
/* Class StructuredClass */
StructuredClass::StructuredClass(Manager &mgr, std::string name,
@@ -341,11 +369,10 @@ bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const
void StructuredClass::addSubclass(Handle<StructuredClass> sc)
{
// check if we already have that class.
- if (subclasses.find(sc) != subclasses.end()) {
- return;
+ if (subclasses.find(sc) == subclasses.end()) {
+ invalidate();
+ subclasses.push_back(sc);
}
- invalidate();
- subclasses.push_back(sc);
sc->setSuperclass(this);
}
@@ -427,21 +454,61 @@ bool Domain::doValidate(Logger &logger) const
void Domain::addStructuredClass(Handle<StructuredClass> s)
{
- invalidate();
- structuredClasses.push_back(s);
- if (s->getParent() != this) {
+ // only add it if we need to.
+ if (structuredClasses.find(s) == structuredClasses.end()) {
+ invalidate();
+ structuredClasses.push_back(s);
+ }
+ Handle<Managed> par = s->getParent();
+ if (par != this) {
+ if (par != nullptr) {
+ // remove the StructuredClass from the old parent.
+ par.cast<Domain>()->removeStructuredClass(s);
+ }
s->setParent(this);
}
}
+bool Domain::removeStructuredClass(Handle<StructuredClass> s)
+{
+ auto it = structuredClasses.find(s);
+ if (it != structuredClasses.end()) {
+ invalidate();
+ structuredClasses.erase(it);
+ s->setParent(nullptr);
+ return true;
+ }
+ return false;
+}
+
void Domain::addAnnotationClass(Handle<AnnotationClass> a)
{
- invalidate();
- annotationClasses.push_back(a);
- if (a->getParent() != this) {
+ // only add it if we need to.
+ if (annotationClasses.find(a) == annotationClasses.end()) {
+ invalidate();
+ annotationClasses.push_back(a);
+ }
+ Handle<Managed> par = a->getParent();
+ if (par != this) {
+ if (par != nullptr) {
+ // remove the StructuredClass from the old parent.
+ par.cast<Domain>()->removeAnnotationClass(a);
+ }
a->setParent(this);
}
}
+
+bool Domain::removeAnnotationClass(Handle<AnnotationClass> a)
+{
+ auto it = annotationClasses.find(a);
+ if (it != annotationClasses.end()) {
+ invalidate();
+ annotationClasses.erase(it);
+ a->setParent(nullptr);
+ return true;
+ }
+ return false;
+}
}
/* Type registrations */
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 85caa14..12cb9b3 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -510,33 +510,21 @@ public:
/**
* Adds the given FieldDescriptor to this Descriptor. This also sets the
* parent of the given FieldDescriptor if it is not set to this Descriptor
- * already.
- *
- * This should not be used if the given FieldDescriptor is a field of
- * another Descriptor already. Use copyFieldDescriptor in that case.
- * TODO: But this could get move semantics.
+ * already and removes it from the old parent Descriptor.
*
* @param fd is a FieldDescriptor.
*/
- void addFieldDescriptor(Handle<FieldDescriptor> fd)
- {
- invalidate();
- fieldDescriptors.push_back(fd);
- if (fd->getParent() != this) {
- fd->setParent(this);
- }
- }
+ void addFieldDescriptor(Handle<FieldDescriptor> fd);
/**
* Adds the given FieldDescriptors to this Descriptor. This also sets the
* parent of each given FieldDescriptor if it is not set to this Descriptor
- * already.
+ * already and removes it from the old parent Descriptor.
*
* @param fds are FieldDescriptors.
*/
void addFieldDescriptors(const std::vector<Handle<FieldDescriptor>> &fds)
{
- invalidate();
for (Handle<FieldDescriptor> fd : fds) {
addFieldDescriptor(fd);
}
@@ -551,6 +539,16 @@ public:
void copyFieldDescriptor(Handle<FieldDescriptor> fd);
/**
+ * Removes the given FieldDescriptor from this Descriptor. This also sets
+ * the parent of the given FieldDescriptor to null.
+ *
+ * @param fd is a FieldDescriptor.
+ * @return true if the FieldDescriptor was removed and false if this
+ * Descriptor did not have the given FieldDescriptor as child.
+ */
+ bool removeFieldDescriptor(Handle<FieldDescriptor> fd);
+
+ /**
* This tries to construct the shortest possible path of this Descriptor
* to the given child Descriptor. As an example consider the book domain
* from above.
@@ -877,13 +875,7 @@ private:
protected:
void doResolve(ResolutionState &state) override;
- /*
- * TODO: doValidate with:
- * # namecheck
- * # are all structureclasses valid and have a unique name?
- * # are all annotationclasses valid and have a unique name?
- * # are all typesystems valid?
- */
+
bool doValidate(Logger &logger) const override;
public:
@@ -931,14 +923,24 @@ public:
}
/**
* Adds a StructuredClass to this domain. This also sets the parent of the
- * given StructuredClass if it is not set to this Domain already.
- * TODO: This could have move semantics.
+ * given StructuredClass if it is not set to this Domain already and removes
+ * it from the old Domain.
*
* @param s is some StructuredClass.
*/
void addStructuredClass(Handle<StructuredClass> s);
/**
+ * Removes a StructuredClass from this domain. This also sets the parent of
+ * the given StructuredClass to null.
+ *
+ * @param s is some StructuredClass.
+ * @return true if the given StructuredClass was removed and false if this
+ * Domain did not have the given StructuredClass as child.
+ */
+ bool removeStructuredClass(Handle<StructuredClass> s);
+
+ /**
* Returns a const reference to the NodeVector of AnnotationClasses that are
* part of this Domain.
*
@@ -951,14 +953,24 @@ public:
}
/**
* Adds an AnnotationClass to this domain. This also sets the parent of the
- * given AnnotationClass if it is not set to this Domain already.
- * TODO: This could have move semantics.
+ * given AnnotationClass if it is not set to this Domain already and removes
+ * it from the old Domain.
*
* @param a is some AnnotationClass.
*/
void addAnnotationClass(Handle<AnnotationClass> a);
/**
+ * Removes a AnnotationClass from this domain. This also sets the parent of
+ * the given AnnotationClass to null.
+ *
+ * @param a is some AnnotationClass.
+ * @return true if the given AnnotationClass was removed and false if this
+ * Domain did not have the given AnnotationClass as child.
+ */
+ bool removeAnnotationClass(Handle<AnnotationClass> a);
+
+ /**
* Returns a const reference to the NodeVector of TypeSystems that are
* references in this Domain.
*