diff --git a/alib2data/src/common/base.hpp b/alib2data/src/common/base.hpp
index 526d14da2079a73b3168d5edf36516fe03c69696..01f536be0908b46a6745b79f04e5e62e0e61ca21 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 82425597fa4755bdb369ff98e7cc0f2ef8ff27cf..b97e62d8c5c35638979434b7ed0452819b90b106 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 59794b6b38e0aa38b62461d2a6cd67660f9f61a9..40240a7a9eb36492d5e84a97fc32b195b56be869 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 17db046d994332aa7840052b4dc3b5c9135544f6..0000000000000000000000000000000000000000
--- 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 26b5801e3e5e318fcf608df9f5e78f92687cd6a1..16601411ec412554e0b1d8036bc0ecc06d5f1c5d 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 e4824063f3e7be647cd72e758ac4c55f43ab1593..189272ee11c957fed5f6f1405607cdc30c18bf37 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 bba5ca7e4fae07262dc277598bc8736985a30bc0..b1e1008a00fea5db0cb6921df5ee8e9a7b8e5a9a 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 ef282ae9f281f19a40fba8dfc6d99041848489f1..91e35b787d308636f4a5b373e8bb758b6589bb4b 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 00d16b62a1462ab39aa9110ca1c48a6e49187b71..01005f14bfc0d4183bc12708014de53076132f0c 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 680355fe0d3646c7f6ba85ae8e0bc48baf2d58e4..fe5bbcb08ab6e235c1e4c7a18e91b7337d44e8db 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 2b1f23ff06456780f6486b7aefe15a9466417f35..6aef5c443ebc09b3ed143ede0e244b985c07956e 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 */