summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/managed/ManagedContainer.hpp11
-rw-r--r--src/core/model/Document.hpp8
-rw-r--r--src/core/model/Domain.hpp41
-rw-r--r--src/core/model/Typesystem.hpp2
-rw-r--r--test/core/managed/ManagedContainerTest.cpp41
-rw-r--r--test/core/model/DocumentTest.cpp12
-rw-r--r--test/core/model/ModelTestUtils.hpp90
7 files changed, 176 insertions, 29 deletions
diff --git a/src/core/managed/ManagedContainer.hpp b/src/core/managed/ManagedContainer.hpp
index 19bff3f..6bf1915 100644
--- a/src/core/managed/ManagedContainer.hpp
+++ b/src/core/managed/ManagedContainer.hpp
@@ -32,6 +32,7 @@
#include <unordered_set>
#include <vector>
#include <map>
+#include <stdexcept>
#include <type_traits>
#include "Manager.hpp"
@@ -496,6 +497,16 @@ public:
}
Base::c.pop_back();
}
+
+ Rooted<T> operator[](int i) const {
+ for (const_iterator it = Base::cbegin(); it != Base::cend(); it++) {
+ if (i == 0) {
+ return Rooted<T>(*it);
+ }
+ i--;
+ }
+ throw std::out_of_range(std::to_string(i) + " is out of range!");
+ }
};
/**
diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp
index 3114480..a31e52f 100644
--- a/src/core/model/Document.hpp
+++ b/src/core/model/Document.hpp
@@ -26,9 +26,11 @@
*
* A Document, from top to bottom, consists of "Document" instance,
* which "owns" the structural root node of the in-document graph. This might
- * for example be a "book" node, if the respective document implements the
- * "book" domain. That root node in turn has structure nodes as children as well
- * as annotations that refer to the content of that structure node.
+ * for example be a "book" node of the "book" domain. That root node in turn has
+ * structure nodes as children, which in turn may have children. This
+ * constitutes a Structure Tree. Additionally annotations may be attached to
+ * Structure Nodes, effectively resulting in a Document Graph instead of a
+ * Document Tree (other references may introduce cycles as well).
*
* Consider this simplified XML representation of a document (TODO: Use
* non-simplified XML as soon as possible):
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 9ae8871..e348136 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -91,8 +91,9 @@
namespace ousia {
namespace model {
-class StructuredClass;
class Descriptor;
+class StructuredClass;
+class Domain;
/**
* As mentioned in the description above a FieldDescriptor specifies the
@@ -147,17 +148,18 @@ public:
* set to "PRIMITIVE".
*
* @param mgr is the global Manager instance.
- * @param name is the name of this field.
* @param parent is a handle of the Descriptor node that has this
* FieldDescriptor.
* @param primitiveType is a handle to some Type in some Typesystem of which
* one instance is allowed to fill this field.
+ * @param name is the name of this field.
* @param optional should be set to 'false' is this field needs to be
* filled in order for an instance of the parent
* Descriptor to be valid.
*/
- FieldDescriptor(Manager &mgr, std::string name, Handle<Descriptor> parent,
- Handle<Type> primitiveType, bool optional)
+ FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
+ Handle<Type> primitiveType, std::string name = "",
+ bool optional = false)
: Node(mgr, std::move(name), parent),
children(this),
fieldType(FieldType::PRIMITIVE),
@@ -171,18 +173,19 @@ public:
* children here.
*
* @param mgr is the global Manager instance.
- * @param name is the name of this field.
* @param parent is a handle of the Descriptor node that has this
* FieldDescriptor.
* @param fieldType is the FieldType of this FieldDescriptor, either
* TREE for the main or default structure or SUBTREE
* for supporting structures.
+ * @param name is the name of this field.
* @param optional should be set to 'false' is this field needs to be
* filled in order for an instance of the parent
* Descriptor to be valid.
*/
- FieldDescriptor(Manager &mgr, std::string name, Handle<Descriptor> parent,
- FieldType fieldType, bool optional)
+ FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
+ FieldType fieldType = FieldType::TREE,
+ std::string name = "", bool optional = false)
: Node(mgr, std::move(name), parent),
children(this),
fieldType(fieldType),
@@ -239,10 +242,10 @@ private:
ManagedVector<FieldDescriptor> fieldDescriptors;
public:
- Descriptor(Manager &mgr, std::string name, Handle<Node> parent,
+ Descriptor(Manager &mgr, std::string name, Handle<Domain> domain,
// TODO: What would be a wise default value for attributes?
Handle<StructType> attributesDescriptor)
- : Node(mgr, std::move(name), parent),
+ : Node(mgr, std::move(name), domain),
attributesDescriptor(acquire(attributesDescriptor)),
fieldDescriptors(this)
{
@@ -351,12 +354,13 @@ private:
public:
const bool transparent;
- StructuredClass(Manager &mgr, std::string name, Handle<Node> parent,
- Handle<StructType> attributesDescriptor,
+ StructuredClass(Manager &mgr, std::string name, Handle<Domain> domain,
const Cardinality &cardinality,
+ Handle<StructType> attributesDescriptor = {nullptr},
// TODO: What would be a wise default value for isa?
- Handle<StructuredClass> isa, bool transparent)
- : Descriptor(mgr, std::move(name), parent, attributesDescriptor),
+ Handle<StructuredClass> isa = {nullptr},
+ bool transparent = false)
+ : Descriptor(mgr, std::move(name), domain, attributesDescriptor),
cardinality(cardinality),
isa(acquire(isa)),
parents(this),
@@ -393,13 +397,15 @@ class Domain : public Node {
private:
ManagedVector<StructuredClass> rootStructures;
ManagedVector<AnnotationClass> annotationClasses;
+ ManagedVector<Typesystem> typesystems;
public:
Domain(Manager &mgr, std::string name)
// TODO: Can a domain have a parent?
: Node(mgr, std::move(name), nullptr),
rootStructures(this),
- annotationClasses(this)
+ annotationClasses(this),
+ typesystems(this)
{
}
@@ -423,6 +429,13 @@ public:
{
return annotationClasses;
}
+
+ ManagedVector<Typesystem> &getTypesystems() { return typesystems; }
+
+ const ManagedVector<Typesystem> &getTypesystems() const
+ {
+ return typesystems;
+ }
};
}
}
diff --git a/src/core/model/Typesystem.hpp b/src/core/model/Typesystem.hpp
index 347adb8..90154ce 100644
--- a/src/core/model/Typesystem.hpp
+++ b/src/core/model/Typesystem.hpp
@@ -372,6 +372,8 @@ public:
* TODO: DOC
*/
void addType(Handle<Type> type) { types.push_back(type); }
+
+ const NodeVector<Type> &getTypes() const { return types; }
};
}
}
diff --git a/test/core/managed/ManagedContainerTest.cpp b/test/core/managed/ManagedContainerTest.cpp
index c34541a..7ff819f 100644
--- a/test/core/managed/ManagedContainerTest.cpp
+++ b/test/core/managed/ManagedContainerTest.cpp
@@ -38,7 +38,7 @@ TEST(ManagedVector, managedVector)
{
Rooted<Managed> root{new Managed{mgr}};
- std::vector<TestManaged*> elems;
+ std::vector<TestManaged *> elems;
for (int i = 0; i < nElem; i++) {
elems.push_back(new TestManaged{mgr, a[i]});
}
@@ -49,7 +49,8 @@ TEST(ManagedVector, managedVector)
ManagedVector<TestManaged> v(root, elems.begin(), elems.end());
- // Remove the last element from the list. It should be garbage collected.
+ // Remove the last element from the list. It should be garbage
+ // collected.
v.pop_back();
ASSERT_FALSE(a[nElem - 1]);
@@ -85,7 +86,6 @@ TEST(ManagedVector, managedVector)
}
}
-
TEST(ManagedVector, moveAssignment)
{
constexpr int nElem = 16;
@@ -220,16 +220,39 @@ TEST(ManagedVector, moveWithNewOwner)
}
}
-class TestManagedWithContainer : public Managed {
+TEST(ManagedVector, accessOperator)
+{
+ Manager mgr{1};
+ Rooted<Managed> root{new Managed{mgr}};
+ ManagedVector<Managed> instance{root};
+ Rooted<Managed> elem{new Managed{mgr}};
+ instance.push_back(elem);
+
+ ASSERT_EQ(elem, instance[0]);
+
+ // Test out of bounds.
+ bool caught = false;
+ try {
+ instance[1];
+ }
+ catch (std::out_of_range ex) {
+ caught = true;
+ }
+ ASSERT_TRUE(caught);
+
+ instance.push_back(elem);
+ ASSERT_EQ(elem, instance[1]);
+}
+class TestManagedWithContainer : public Managed {
public:
ManagedVector<TestManaged> elems;
- TestManagedWithContainer(Manager &mgr) : Managed(mgr), elems(this) {};
-
+ TestManagedWithContainer(Manager &mgr) : Managed(mgr), elems(this){};
};
-TEST(ManagedVector, embedded) {
+TEST(ManagedVector, embedded)
+{
// Note: This test depends on the correct deletion order -- otherwise
// valgrind shows an error
bool a;
@@ -248,7 +271,6 @@ TEST(ManagedVector, embedded) {
ASSERT_FALSE(a);
}
-
TEST(ManagedMap, managedMap)
{
// TODO: This test is highly incomplete
@@ -260,7 +282,7 @@ TEST(ManagedMap, managedMap)
{
Rooted<Managed> root{new Managed{mgr}};
- std::map<int, TestManaged*> elems;
+ std::map<int, TestManaged *> elems;
for (int i = 0; i < nElem; i++) {
elems.insert(std::make_pair(i, new TestManaged{mgr, a[i]}));
}
@@ -298,6 +320,5 @@ TEST(ManagedMap, managedMap)
ASSERT_FALSE(v);
}
}
-
}
diff --git a/test/core/model/DocumentTest.cpp b/test/core/model/DocumentTest.cpp
index 36e7c02..dd883a4 100644
--- a/test/core/model/DocumentTest.cpp
+++ b/test/core/model/DocumentTest.cpp
@@ -20,12 +20,20 @@
#include <core/model/Document.hpp>
+#include "ModelTestUtils.hpp"
+
namespace ousia {
namespace model {
+
+
TEST(Document, testDocumentConstruction)
{
- // Start by constructing the domain.
- //TODO: IMPLEMENT
+ // Construct Manager
+ Manager mgr{1};
+ // Get the domain.
+ Rooted<Domain> domain = constructBookDomain(mgr);
+
+ // TODO: IMPLEMENT
ASSERT_TRUE(true);
}
}
diff --git a/test/core/model/ModelTestUtils.hpp b/test/core/model/ModelTestUtils.hpp
new file mode 100644
index 0000000..665e351
--- /dev/null
+++ b/test/core/model/ModelTestUtils.hpp
@@ -0,0 +1,90 @@
+/*
+ Ousía
+ Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _MODEL_TEST_UTILS_HPP_
+#define _MODEL_TEST_UTILS_HPP_
+
+#include <core/model/Domain.hpp>
+#include <core/model/Typesystem.hpp>
+
+namespace ousia {
+namespace model {
+
+/**
+ * This constructs a somewhat trivial system of standard types.
+ *
+ * Currently contained: string
+ */
+static Rooted<Typesystem> constructTypeSystem(Manager &mgr)
+{
+ Rooted<Typesystem> sys{new Typesystem(mgr, "std")};
+ Rooted<StringType> string{new StringType(mgr, sys)};
+ sys->addType(string);
+
+ return sys;
+}
+
+/**
+ * This constructs the "book" domain for test purposes. The structure of the
+ * domain is fairly and can be seen from the construction itself.
+ */
+static Rooted<Domain> constructBookDomain(Manager &mgr)
+{
+ // Start with the Domain itself.
+ Rooted<Domain> domain{new Domain(mgr, "book")};
+ // The standard type system.
+ domain->getTypesystems().push_back(constructTypeSystem(mgr));
+ // Set up the cardinalities we'll need.
+ Cardinality single;
+ single.merge({1});
+ Cardinality any;
+ any.merge(Range<size_t>::typeRangeFrom(0));
+
+ // Set up the "book" node.
+ Rooted<StructuredClass> book{
+ new StructuredClass(mgr, "book", domain, single)};
+ domain->getRootStructures().push_back(book);
+ // The structure field of it.
+ Rooted<FieldDescriptor> book_field{new FieldDescriptor(mgr, book)};
+ book->getFieldDescriptors().push_back(book_field);
+
+ // From there on the "section".
+ Rooted<StructuredClass> section{
+ new StructuredClass(mgr, "section", domain, any)};
+ book_field->getChildren().push_back(section);
+ // And the field of it.
+ Rooted<FieldDescriptor> section_field{new FieldDescriptor(mgr, section)};
+ section->getFieldDescriptors().push_back(section_field);
+
+ // We also add the "paragraph", which is transparent.
+ Rooted<StructuredClass> paragraph{new StructuredClass(
+ mgr, "paragraph", domain, any, {nullptr}, {nullptr}, true)};
+ section_field->getChildren().push_back(paragraph);
+ book_field->getChildren().push_back(paragraph);
+ // ... and has a primitive field.
+ Rooted<FieldDescriptor> text{new FieldDescriptor(
+ mgr, paragraph, domain->getTypesystems()[0]->getTypes()[0], "text",
+ false)};
+
+ return domain;
+}
+}
+}
+
+#endif /* _TEST_MANAGED_H_ */
+