diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2014-12-17 11:44:36 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2014-12-17 11:44:36 +0100 |
commit | 6dd18a83a1f2c89c5bca435090c80d72cb8716e3 (patch) | |
tree | 7d982490cc45f9ef6f383850a71fa3ceb1ff3650 /src | |
parent | f1d768733c8b9166bbfb6943567b01b9d6fbcb15 (diff) |
First draft of Cardinality. There are still semantic improvements to be made, though.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/model/Cardinality.hpp | 181 | ||||
-rw-r--r-- | src/core/model/Domain.hpp | 55 |
2 files changed, 211 insertions, 25 deletions
diff --git a/src/core/model/Cardinality.hpp b/src/core/model/Cardinality.hpp new file mode 100644 index 0000000..aad5891 --- /dev/null +++ b/src/core/model/Cardinality.hpp @@ -0,0 +1,181 @@ +/* + 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/>. +*/ + +/** + * @file Cardinality.hpp + * + * A Cardinality in this term here is some arbitrary subset of natural numbers + * (including zero), that specifies the permits size of some other set. + * + * We define Cardinalities in a constructive process, meaning constructive + * operators on elementary sets (either single numbers or ranges of numbers). + * + * Examples for such constructions are: + * + * {1} + * {1,...,4} + * {1,...,4} union {9,...,12} union {16} + * {0,...,infinity} + * + * Note that the only construction operator needed is union (or +). + * + * @author Benjamin Paaßen (bpaassen@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_MODEL_CARDINALITY_HPP_ +#define _OUSIA_MODEL_CARDINALITY_HPP_ + +namespace ousia { +namespace model { + +/** + * This class is an abstract interface for Cardinality implementations, meaning + * either a Union of two other Cardinalities or elementary Cardinalities. + */ +class Cardinality { +public: + /** + * Returns true if and only if the given size is permits according to this + * Cardinality. + * + * @param is some natural number (size). + * @return true if and only if that size is permits. + */ + virtual bool permits(const size_t &size) const = 0; + + virtual bool operator==(const Cardinality &rhs) const = 0; +}; + +/** + * A UnionCardinality is in fact just the binary or applied to the + * permits-criteria of two other cardinalities. + */ +class UnionCardinality : public Cardinality { +private: + const Cardinality &left; + const Cardinality &right; + +public: + UnionCardinality(const Cardinality &left, const Cardinality &right) + : left(left), right(right) + { + } + + bool permits(const size_t &size) const override + { + return left.permits(size) || right.permits(size); + } + + bool operator==(const Cardinality &obj) const override + { + const UnionCardinality *o = + dynamic_cast<const UnionCardinality *>(&obj); + if (o == NULL) + return false; + return left == o->left && right == o->right; + } +}; + +/** + * The unite function is basically just a wrapper for constructing a + * UnionCardinality. + */ +inline UnionCardinality unite(const Cardinality &lhs, const Cardinality &rhs) +{ + return std::move(UnionCardinality(lhs, rhs)); +} + +/** + * A SingleCardinality permits exactly one number. + */ +class SingleCardinality : public Cardinality { +private: + size_t num; + +public: + SingleCardinality(size_t num) : num(std::move(num)) {} + + bool permits(const size_t &size) const override { return size == num; } + + bool operator==(const Cardinality &obj) const override + { + const SingleCardinality *o = + dynamic_cast<const SingleCardinality *>(&obj); + if (o == NULL) + return false; + return num == o->num; + } +}; + +/** + * A RangeCardinality permits all numbers between the two bounds (lo and hi), + * inclusively. + */ +class RangeCardinality : public Cardinality { +private: + size_t lo; + size_t hi; + +public: + RangeCardinality(size_t lo, size_t hi) + : lo(std::move(lo)), hi(std::move(hi)) + { + } + + bool permits(const size_t &size) const override + { + return size >= lo && size <= hi; + } + + bool operator==(const Cardinality &obj) const override + { + const RangeCardinality *o = + dynamic_cast<const RangeCardinality *>(&obj); + if (o == NULL) + return false; + return lo == o->lo && hi == o->hi; + } +}; + +/** + * An OpenRangeCardinality permits all numbers higher or equal than the lower + * bound. + */ +class OpenRangeCardinality : public Cardinality { +private: + size_t lo; + +public: + OpenRangeCardinality(size_t lo) : lo(std::move(lo)) {} + + bool permits(const size_t &size) const override { return size >= lo; } + + bool operator==(const Cardinality &obj) const override + { + const OpenRangeCardinality *o = + dynamic_cast<const OpenRangeCardinality *>(&obj); + if (o == NULL) + return false; + return lo == o->lo; + } +}; +} +} + +#endif /* _OUSIA_MODEL_CARDINALITY_HPP_ */ + diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index 50c0bb1..65b9b1d 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -85,6 +85,7 @@ #include <core/managed/ManagedContainer.hpp> #include <core/Node.hpp> +#include "Cardinality.hpp" #include "Typesystem.hpp" namespace ousia { @@ -181,10 +182,9 @@ public: * Descriptor to be valid. */ FieldDescriptor(Manager &mgr, std::string name, Handle<Descriptor> parent, - FieldType fieldType, - ManagedVector<StructuredClass> children, bool optional) + FieldType fieldType, bool optional) : Node(mgr, std::move(name), parent), - children(children), + children(this), fieldType(fieldType), // TODO: What would be a wise initialization of the primitiveType? optional(optional) @@ -194,6 +194,11 @@ public: // TODO: Is returning a ManagedVector alright? ManagedVector<StructuredClass> &getChildren() { return children; } + const ManagedVector<StructuredClass> &getChildren() const + { + return children; + } + FieldType getFieldType() const { return fieldType; } bool isPrimitive() const { return fieldType == FieldType::PRIMITIVE; } @@ -236,11 +241,10 @@ private: public: Descriptor(Manager &mgr, std::string name, Handle<Node> parent, // TODO: What would be a wise default value for attributes? - Handle<StructType> attributesDescriptor, - ManagedVector<FieldDescriptor> fieldDescriptors) + Handle<StructType> attributesDescriptor) : Node(mgr, std::move(name), parent), attributesDescriptor(acquire(attributesDescriptor)), - fieldDescriptors(fieldDescriptors) + fieldDescriptors(this) { } @@ -261,10 +265,6 @@ public: } }; -// TODO: Implement -class Cardinality { -}; - /** * A StructuredClass specifies nodes in the StructureTree of a document that * implements this domain. For more information on the StructureTree please @@ -342,7 +342,7 @@ class Cardinality { */ class StructuredClass : public Descriptor { private: - const Cardinality cardinality; + const Cardinality& cardinality; Owned<StructuredClass> isa; ManagedVector<FieldDescriptor> parents; @@ -351,16 +351,13 @@ public: StructuredClass(Manager &mgr, std::string name, Handle<Node> parent, Handle<StructType> attributesDescriptor, - ManagedVector<FieldDescriptor> fieldDescriptors, const Cardinality &cardinality, // TODO: What would be a wise default value for isa? - Handle<StructuredClass> isa, - ManagedVector<FieldDescriptor> parents, bool transparent) - : Descriptor(mgr, std::move(name), parent, attributesDescriptor, - fieldDescriptors), + Handle<StructuredClass> isa, bool transparent) + : Descriptor(mgr, std::move(name), parent, attributesDescriptor), cardinality(cardinality), isa(acquire(isa)), - parents(parents), + parents(this), transparent(transparent) { } @@ -370,7 +367,7 @@ public: Rooted<StructuredClass> getIsA() const { return isa; } // TODO: Is returning a ManagedVector alright? - ManagedVector<FieldDescriptor>& getParents() { return parents; } + ManagedVector<FieldDescriptor> &getParents() { return parents; } const ManagedVector<FieldDescriptor> &getParents() const { return parents; } }; @@ -396,23 +393,31 @@ private: ManagedVector<AnnotationClass> annotationClasses; public: - Domain(Manager &mgr, std::string name, - ManagedVector<StructuredClass> rootStructures, - ManagedVector<AnnotationClass> annotationClasses) + Domain(Manager &mgr, std::string name) // TODO: Can a domain have a parent? : Node(mgr, std::move(name), nullptr), - rootStructures(rootStructures), - annotationClasses(annotationClasses) + rootStructures(this), + annotationClasses(this) { } // TODO: Is returning a ManagedVector alright? - ManagedVector<StructuredClass> getRootStructures() + ManagedVector<StructuredClass> &getRootStructures() + { + return rootStructures; + } + + const ManagedVector<StructuredClass> &getRootStructures() const { return rootStructures; } - ManagedVector<AnnotationClass> getAnnotationClasses() + ManagedVector<AnnotationClass> &getAnnotationClasses() + { + return annotationClasses; + } + + const ManagedVector<AnnotationClass> &getAnnotationClasses() const { return annotationClasses; } |