summaryrefslogtreecommitdiff
path: root/src/core/model/Cardinality.hpp
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-17 11:44:36 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-17 11:44:36 +0100
commit6dd18a83a1f2c89c5bca435090c80d72cb8716e3 (patch)
tree7d982490cc45f9ef6f383850a71fa3ceb1ff3650 /src/core/model/Cardinality.hpp
parentf1d768733c8b9166bbfb6943567b01b9d6fbcb15 (diff)
First draft of Cardinality. There are still semantic improvements to be made, though.
Diffstat (limited to 'src/core/model/Cardinality.hpp')
-rw-r--r--src/core/model/Cardinality.hpp181
1 files changed, 181 insertions, 0 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_ */
+