From 99d8cf85f88b667bfabf8d70e867732aa6293fe1 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 12 Aug 2014 14:01:41 +0200
Subject: [PATCH] templated label data base class

---
 alib2data/src/common/base.hpp                 | 45 +++++++++----
 alib2data/src/label/CharacterLabel.h          |  4 ++
 alib2data/src/label/IntegerLabel.h            |  4 ++
 alib2data/src/label/LabelBase.cpp             | 63 -------------------
 alib2data/src/label/LabelBase.h               | 42 +------------
 alib2data/src/label/StringLabel.h             |  4 ++
 alib2data/src/regexp/formal/FormalRegExp.h    |  4 ++
 .../src/regexp/unbounded/UnboundedRegExp.h    |  3 +
 alib2data/src/string/CyclicString.h           |  3 +
 alib2data/src/string/Epsilon.h                |  3 +
 alib2data/src/string/LinearString.h           |  3 +
 11 files changed, 63 insertions(+), 115 deletions(-)
 delete mode 100644 alib2data/src/label/LabelBase.cpp

diff --git a/alib2data/src/common/base.hpp b/alib2data/src/common/base.hpp
index 526d14da20..01f536be09 100644
--- a/alib2data/src/common/base.hpp
+++ b/alib2data/src/common/base.hpp
@@ -13,18 +13,33 @@
 
 namespace alib {
 
-template<typename... Types>
+template<int ID>
+class base_base {
+public:
+	template<typename T>
+	int typeId(const T&) const {
+		return ID;
+	}
+
+	virtual int selfTypeId() const = 0;
+};
+
+template<int ID, typename... Types>
 class base_helper;
 
-template<typename T>
-class base_helper<T> {
+template<int ID, typename T>
+class base_helper<ID, T> : public base_base<ID + 1> {
 public:
+	virtual int typeId(const T &) const {
+		return ID;
+	}
+
 	virtual bool operator==(const T &) const {
 		return false;
 	}
 
 	virtual bool operator<(const T & other) const {
-		return typeid(this).before(typeid(&other));
+		return this->selfTypeId() < typeId(other);
 	}
 
 	virtual ~base_helper() noexcept {
@@ -32,26 +47,32 @@ public:
 	}
 };
 
-template<typename T, typename... Types>
-class base_helper<T, Types...> : public base_helper<Types...> {
+template<int ID, typename T, typename... Types>
+class base_helper<ID, T, Types...> : public base_helper<ID + 1, Types...> {
 public:
-	using base_helper<Types...>::operator==;
-	using base_helper<Types...>::operator<;
+	using base_helper<ID + 1, Types...>::operator==;
+	using base_helper<ID + 1, Types...>::operator<;
+	using base_helper<ID + 1, Types...>::typeId;
+
+	virtual int typeId(const T &) const {
+		return ID;
+	}
 
 	virtual bool operator==(const T &) const {
 		return false;
 	}
 
 	virtual bool operator<(const T & other) const {
-		return typeid(this).before(typeid(&other));
+		return this->selfTypeId() < typeId(other);
 	}
 };
 
 template<typename T, typename... Types>
-class base : public base_helper<Types...> {
+class base : public base_helper<1, Types...> {
 public:
-	using base_helper<Types...>::operator==;
-	using base_helper<Types...>::operator<;
+	using base_helper<1, Types...>::operator==;
+	using base_helper<1, Types...>::operator<;
+	using base_helper<1, Types...>::typeId;
 
 	virtual T* clone() const = 0;
 
diff --git a/alib2data/src/label/CharacterLabel.h b/alib2data/src/label/CharacterLabel.h
index 82425597fa..b97e62d8c5 100644
--- a/alib2data/src/label/CharacterLabel.h
+++ b/alib2data/src/label/CharacterLabel.h
@@ -49,6 +49,10 @@ public:
 	virtual void operator>>(std::ostream&) const;
 
 	virtual operator std::string () const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace label */
diff --git a/alib2data/src/label/IntegerLabel.h b/alib2data/src/label/IntegerLabel.h
index 59794b6b38..40240a7a9e 100644
--- a/alib2data/src/label/IntegerLabel.h
+++ b/alib2data/src/label/IntegerLabel.h
@@ -49,6 +49,10 @@ public:
 	virtual void operator>>(std::ostream&) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace label */
diff --git a/alib2data/src/label/LabelBase.cpp b/alib2data/src/label/LabelBase.cpp
deleted file mode 100644
index 17db046d99..0000000000
--- a/alib2data/src/label/LabelBase.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * LabelBase.cpp
- *
- *  Created on: Apr 16, 2013
- *      Author: Jan Travnicek
- */
-
-#include "LabelBase.h"
-#include <typeinfo>
-
-#include "StringLabel.h"
-#include "IntegerLabel.h"
-#include "CharacterLabel.h"
-
-namespace label {
-
-LabelBase::~LabelBase() {
-
-}
-
-bool LabelBase::operator<(const StringLabel& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool LabelBase::operator<(const IntegerLabel& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool LabelBase::operator<(const CharacterLabel& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool LabelBase::operator>=(const LabelBase& other) const {
-	return !(*this < other);
-}
-
-bool LabelBase::operator<=(const LabelBase& other) const {
-	return !(*this > other);
-}
-
-bool LabelBase::operator!=(const LabelBase& other) const {
-	return !(*this == other);
-}
-
-bool LabelBase::operator==(const StringLabel&) const {
-	return false;
-}
-
-bool LabelBase::operator==(const IntegerLabel&) const {
-	return false;
-}
-
-bool LabelBase::operator==(const CharacterLabel&) const {
-	return false;
-}
-
-std::ostream& operator<<(std::ostream& os, const LabelBase& label) {
-	label >> os;
-	return os;
-}
-
-} /* namespace label */
-
diff --git a/alib2data/src/label/LabelBase.h b/alib2data/src/label/LabelBase.h
index 26b5801e3e..16601411ec 100644
--- a/alib2data/src/label/LabelBase.h
+++ b/alib2data/src/label/LabelBase.h
@@ -9,7 +9,7 @@
 #define LABEL_BASE_H_
 
 #include "../std/visitor.hpp"
-#include <iostream>
+#include "../common/base.hpp"
 
 namespace label {
 
@@ -20,45 +20,7 @@ class CharacterLabel;
 /**
  * Abstract base class for all automata.
  */
-class LabelBase : public std::elementBase<StringLabel, IntegerLabel, CharacterLabel> {
-public:
-	virtual LabelBase* clone() const = 0;
-
-	virtual LabelBase* plunder() && = 0;
-
-	virtual ~LabelBase() noexcept;
-
-	virtual bool operator<(const LabelBase& other) const = 0;
-
-	virtual bool operator<(const StringLabel& other) const;
-
-	virtual bool operator<(const IntegerLabel& other) const;
-
-	virtual bool operator<(const CharacterLabel& other) const;
-
-	virtual bool operator>(const LabelBase& other) const = 0;
-
-
-	bool operator>=(const LabelBase& other) const;
-
-	bool operator<=(const LabelBase& other) const;
-
-	bool operator!=(const LabelBase& other) const;
-
-
-	virtual bool operator==(const LabelBase& other) const = 0;
-
-	virtual bool operator==(const StringLabel& other) const;
-
-	virtual bool operator==(const IntegerLabel& other) const;
-
-	virtual bool operator==(const CharacterLabel& other) const;
-
-	friend std::ostream& operator<<(std::ostream& os, const LabelBase& label);
-
-	virtual void operator>>(std::ostream&) const = 0;
-
-	virtual operator std::string() const = 0;
+class LabelBase : public alib::base<LabelBase, StringLabel, IntegerLabel, CharacterLabel>, public std::elementBase<StringLabel, IntegerLabel, CharacterLabel> {
 };
 
 } /* namespace label */
diff --git a/alib2data/src/label/StringLabel.h b/alib2data/src/label/StringLabel.h
index e4824063f3..189272ee11 100644
--- a/alib2data/src/label/StringLabel.h
+++ b/alib2data/src/label/StringLabel.h
@@ -50,6 +50,10 @@ public:
 	virtual void operator>>(std::ostream&) const;
 
 	virtual operator std::string () const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace label */
diff --git a/alib2data/src/regexp/formal/FormalRegExp.h b/alib2data/src/regexp/formal/FormalRegExp.h
index bba5ca7e4f..b1e1008a00 100644
--- a/alib2data/src/regexp/formal/FormalRegExp.h
+++ b/alib2data/src/regexp/formal/FormalRegExp.h
@@ -131,6 +131,10 @@ public:
 	virtual bool operator<(const FormalRegExp& other) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.h b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
index ef282ae9f2..91e35b787d 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExp.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
@@ -132,6 +132,9 @@ public:
 
 	virtual operator std::string() const;
 
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/string/CyclicString.h b/alib2data/src/string/CyclicString.h
index 00d16b62a1..01005f14bf 100644
--- a/alib2data/src/string/CyclicString.h
+++ b/alib2data/src/string/CyclicString.h
@@ -65,6 +65,9 @@ public:
 
 	virtual operator std::string() const;
 
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace string */
diff --git a/alib2data/src/string/Epsilon.h b/alib2data/src/string/Epsilon.h
index 680355fe0d..fe5bbcb08a 100644
--- a/alib2data/src/string/Epsilon.h
+++ b/alib2data/src/string/Epsilon.h
@@ -60,6 +60,9 @@ public:
 
 	static Epsilon EPSILON;
 
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace string */
diff --git a/alib2data/src/string/LinearString.h b/alib2data/src/string/LinearString.h
index 2b1f23ff06..6aef5c443e 100644
--- a/alib2data/src/string/LinearString.h
+++ b/alib2data/src/string/LinearString.h
@@ -73,6 +73,9 @@ public:
 
 	virtual operator std::string() const;
 
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace string */
-- 
GitLab