diff options
Diffstat (limited to 'src/core')
| -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;  	}  | 
