From 2088f890ca80c94cdc6558a2ce5725e4279187f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Uhl=C3=ADk?= <jan@uhlik.me>
Date: Thu, 29 Mar 2018 20:07:54 +0200
Subject: [PATCH] Add basic edge classes Edge, WeightedEdge and CapacityEdge.

---
 alib2graph_data/src/edge/Edge.cpp             |  17 ++
 alib2graph_data/src/edge/Edge.hpp             | 129 +++++++++++++++
 alib2graph_data/src/edge/EdgeBase.hpp         |  32 ++++
 alib2graph_data/src/edge/EdgeClasses.hpp      |  17 ++
 alib2graph_data/src/edge/EdgeFeatures.hpp     |  30 ++++
 .../src/edge/EdgeNormalization.hpp            |  72 ++++++++
 .../src/edge/capacity/CapacityEdge.cpp        |  17 ++
 .../src/edge/capacity/CapacityEdge.hpp        | 154 ++++++++++++++++++
 .../src/edge/weighted/WeightedEdge.cpp        |  18 ++
 .../src/edge/weighted/WeightedEdge.hpp        | 153 +++++++++++++++++
 10 files changed, 639 insertions(+)
 create mode 100644 alib2graph_data/src/edge/Edge.cpp
 create mode 100644 alib2graph_data/src/edge/Edge.hpp
 create mode 100644 alib2graph_data/src/edge/EdgeBase.hpp
 create mode 100644 alib2graph_data/src/edge/EdgeClasses.hpp
 create mode 100644 alib2graph_data/src/edge/EdgeFeatures.hpp
 create mode 100644 alib2graph_data/src/edge/EdgeNormalization.hpp
 create mode 100644 alib2graph_data/src/edge/capacity/CapacityEdge.cpp
 create mode 100644 alib2graph_data/src/edge/capacity/CapacityEdge.hpp
 create mode 100644 alib2graph_data/src/edge/weighted/WeightedEdge.cpp
 create mode 100644 alib2graph_data/src/edge/weighted/WeightedEdge.hpp

diff --git a/alib2graph_data/src/edge/Edge.cpp b/alib2graph_data/src/edge/Edge.cpp
new file mode 100644
index 0000000000..060dc9da84
--- /dev/null
+++ b/alib2graph_data/src/edge/Edge.cpp
@@ -0,0 +1,17 @@
+// Edge.cpp
+//
+//     Created on: 04. 03. 2018
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#include "Edge.hpp"
+#include <registration/ValuePrinterRegistration.hpp>
+
+namespace {
+
+static auto valuePrinter = registration::ValuePrinterRegister<edge::Edge<> >();
+
+}
diff --git a/alib2graph_data/src/edge/Edge.hpp b/alib2graph_data/src/edge/Edge.hpp
new file mode 100644
index 0000000000..ec99c3f209
--- /dev/null
+++ b/alib2graph_data/src/edge/Edge.hpp
@@ -0,0 +1,129 @@
+// Edge.hpp
+//
+//     Created on: 26. 11. 2017
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#ifndef ALIB2_EDGE_HPP
+#define ALIB2_EDGE_HPP
+
+#include <sstream>
+#include <alib/pair>
+#include <alib/tuple>
+#include <object/Object.h>
+#include <object/UniqueObject.h>
+
+#include "EdgeBase.hpp"
+#include "EdgeFeatures.hpp"
+
+namespace edge {
+
+template<typename TNode>
+class Edge : public ext::pair<TNode, TNode>, public EdgeBase {
+// ---------------------------------------------------------------------------------------------------------------------
+ public:
+  using node_type = TNode;
+  using normalized_type = Edge<>;
+
+// ---------------------------------------------------------------------------------------------------------------------
+// =====================================================================================================================
+// Constructor, Destructor, Operators
+
+ public:
+  explicit Edge(TNode _first, TNode _second);
+
+// =====================================================================================================================
+// ObjectBase interface
+
+ public:
+  EdgeBase *clone() const override;
+
+  EdgeBase *plunder() &&override;
+
+  int compare(const object::ObjectBase &other) const override;
+
+  virtual int compare(const Edge &other) const;
+
+  object::ObjectBase *inc() &&override;
+
+  void operator>>(std::ostream &ostream) const override;
+
+  explicit operator std::string() const override;
+
+// =====================================================================================================================
+ public:
+
+  virtual std::string name() const;
+
+// ---------------------------------------------------------------------------------------------------------------------
+};
+// =====================================================================================================================
+
+template<typename TNode>
+Edge<TNode>::Edge(TNode _first, TNode _second)
+    : ext::pair<TNode, TNode>(_first, _second) {
+
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode>
+std::string Edge<TNode>::name() const {
+  return "Edge";
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode>
+EdgeBase *Edge<TNode>::clone() const {
+  return new Edge(*this);
+}
+
+template<typename TNode>
+EdgeBase *Edge<TNode>::plunder() &&{
+  return new Edge(std::move(*this));
+}
+
+template<typename TNode>
+int Edge<TNode>::compare(const object::ObjectBase &other) const {
+  if (ext::type_index(typeid(*this)) == ext::type_index(typeid(other))) return this->compare((decltype(*this)) other);
+  return ext::type_index(typeid(*this)) - ext::type_index(typeid(other));
+}
+
+template<typename TNode>
+int Edge<TNode>::compare(const Edge &other) const {
+  auto one = ext::tie(this->first, this->second);
+  auto two = ext::tie(other.first, other.second);
+
+  static ext::compare<decltype(one)> comp;
+
+  return comp(one, two);
+}
+
+template<typename TNode>
+object::ObjectBase *Edge<TNode>::inc() &&{
+  return new object::UniqueObject(object::Object(std::move(*this)), primitive::Integer(0));
+}
+
+template<typename TNode>
+void Edge<TNode>::operator>>(std::ostream &ostream) const {
+  ostream << "(" << name() << "(first=" << this->first << ", second=" << this->second << "))";
+}
+
+template<typename TNode>
+Edge<TNode>::operator std::string() const {
+  std::stringstream ss;
+  ss << "(" << name() << "(first=" << this->first << ", second=" << this->second << "))";
+  return std::move(ss).str();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+} // namespace edge
+
+// =====================================================================================================================
+
+#endif // ALIB2_EDGE_HPP
diff --git a/alib2graph_data/src/edge/EdgeBase.hpp b/alib2graph_data/src/edge/EdgeBase.hpp
new file mode 100644
index 0000000000..0690b5bb12
--- /dev/null
+++ b/alib2graph_data/src/edge/EdgeBase.hpp
@@ -0,0 +1,32 @@
+// EdgeBase.hpp
+//
+//     Created on: 04. 03. 2018
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#ifndef ALIB2_EDGEBASE_HPP
+#define ALIB2_EDGEBASE_HPP
+
+#include <object/ObjectBase.h>
+
+namespace edge {
+
+/**
+ * Represents edge in graph.
+ */
+class EdgeBase : public object::ObjectBase {
+// ---------------------------------------------------------------------------------------------------------------------
+
+ public:
+  virtual EdgeBase *clone() const = 0;
+  virtual EdgeBase *plunder() &&= 0;
+
+// ---------------------------------------------------------------------------------------------------------------------
+};
+
+} // namespace edge
+
+#endif //ALIB2_EDGEBASE_HPP
diff --git a/alib2graph_data/src/edge/EdgeClasses.hpp b/alib2graph_data/src/edge/EdgeClasses.hpp
new file mode 100644
index 0000000000..e2c099b940
--- /dev/null
+++ b/alib2graph_data/src/edge/EdgeClasses.hpp
@@ -0,0 +1,17 @@
+// EdgeTypes.hpp
+//
+//     Created on: 17. 12. 2017
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#ifndef ALIB2_EDGETYPES_HPP
+#define ALIB2_EDGETYPES_HPP
+
+#include "Edge.hpp"
+#include "weighted/WeightedEdge.hpp"
+#include "capacity/CapacityEdge.hpp"
+
+#endif //ALIB2_EDGETYPES_HPP
diff --git a/alib2graph_data/src/edge/EdgeFeatures.hpp b/alib2graph_data/src/edge/EdgeFeatures.hpp
new file mode 100644
index 0000000000..d1044ed325
--- /dev/null
+++ b/alib2graph_data/src/edge/EdgeFeatures.hpp
@@ -0,0 +1,30 @@
+// EdgeFeatures.hpp
+//
+//     Created on: 01. 03. 2018
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#ifndef ALIB2_EDGEFEATURES_HPP
+#define ALIB2_EDGEFEATURES_HPP
+
+#include <common/default_type/DefaultNodeType.hpp>
+#include <common/default_type/DefaultWeightType.hpp>
+#include <common/default_type/DefaultCapacityType.hpp>
+
+namespace edge {
+
+template<typename TNode = DefaultNodeType>
+class Edge;
+
+template<typename TNode = DefaultNodeType, typename TWeight = DefaultWeightType>
+class WeightedEdge;
+
+template<typename TNode = DefaultNodeType, typename TWeight = DefaultCapacityType>
+class CapacityEdge;
+
+} // namespace edge
+
+#endif //ALIB2_EDGEFEATURES_HPP
diff --git a/alib2graph_data/src/edge/EdgeNormalization.hpp b/alib2graph_data/src/edge/EdgeNormalization.hpp
new file mode 100644
index 0000000000..50489c44ef
--- /dev/null
+++ b/alib2graph_data/src/edge/EdgeNormalization.hpp
@@ -0,0 +1,72 @@
+// EdgeNormalization.hpp
+//
+//     Created on: 04. 03. 2018
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#ifndef ALIB2_EDGENORMALIZATION_HPP
+#define ALIB2_EDGENORMALIZATION_HPP
+
+#include <core/normalize.hpp>
+#include <common/Normalize.hpp>
+
+#include "EdgeClasses.hpp"
+
+namespace core {
+
+/**
+ * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states.
+ *
+ * \returns new instance of the graph with default template parameters or unmodified instance if the template parameters were already the default ones
+ */
+
+template<typename TNode>
+struct normalize<edge::Edge<TNode>, typename std::enable_if<!std::is_same<
+    edge::Edge<TNode>, edge::Edge<> >::value>::type> {
+  static edge::Edge<> eval(edge::Edge<TNode> &&value) {
+    DefaultNodeType first = common::Normalize::normalizeNode(value.first);
+    DefaultNodeType second = common::Normalize::normalizeNode(value.second);
+    return edge::Edge(std::move(first), std::move(second));
+  }
+};
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+/**
+ * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states.
+ *
+ * \returns new instance of the graph with default template parameters or unmodified instance if the template parameters were already the default ones
+ */
+
+template<typename TNode>
+struct normalize<edge::WeightedEdge<TNode>, typename std::enable_if<!std::is_same<
+    edge::WeightedEdge<TNode>, edge::WeightedEdge<> >::value>::type> {
+  static edge::WeightedEdge<> eval(edge::WeightedEdge<TNode> &&value) {
+    return common::Normalize::normalizeWeightedEdge(value);
+  }
+};
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+/**
+ * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states.
+ *
+ * \returns new instance of the graph with default template parameters or unmodified instance if the template parameters were already the default ones
+ */
+
+template<typename TNode>
+struct normalize<edge::CapacityEdge<TNode>, typename std::enable_if<!std::is_same<
+    edge::CapacityEdge<TNode>, edge::CapacityEdge<> >::value>::type> {
+  static edge::WeightedEdge<> eval(edge::WeightedEdge<TNode> &&value) {
+    return common::Normalize::normalizeCapacityEdge(value);
+  }
+};
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+}
+
+#endif //ALIB2_EDGENORMALIZATION_HPP
diff --git a/alib2graph_data/src/edge/capacity/CapacityEdge.cpp b/alib2graph_data/src/edge/capacity/CapacityEdge.cpp
new file mode 100644
index 0000000000..adacf98773
--- /dev/null
+++ b/alib2graph_data/src/edge/capacity/CapacityEdge.cpp
@@ -0,0 +1,17 @@
+// CapacityEdge.cpp
+//
+//     Created on: 28. 03. 2018
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#include "CapacityEdge.hpp"
+#include <registration/ValuePrinterRegistration.hpp>
+
+namespace {
+
+static auto valuePrinter = registration::ValuePrinterRegister<edge::CapacityEdge<> >();
+
+}
diff --git a/alib2graph_data/src/edge/capacity/CapacityEdge.hpp b/alib2graph_data/src/edge/capacity/CapacityEdge.hpp
new file mode 100644
index 0000000000..6a41773575
--- /dev/null
+++ b/alib2graph_data/src/edge/capacity/CapacityEdge.hpp
@@ -0,0 +1,154 @@
+// CapacityEdge.hpp
+//
+//     Created on: 28. 03. 2018
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#ifndef ALIB2_CAPACITYEDGE_HPP
+#define ALIB2_CAPACITYEDGE_HPP
+
+#include <ostream>
+#include <alib/pair>
+#include <object/UniqueObject.h>
+#include <object/Object.h>
+#include <alib/tuple>
+
+#include <edge/EdgeFeatures.hpp>
+#include <edge/EdgeBase.hpp>
+
+namespace edge {
+
+template<typename TNode, typename TCapacity>
+class CapacityEdge : public ext::pair<TNode, TNode>, public EdgeBase {
+// ---------------------------------------------------------------------------------------------------------------------
+ public:
+  using node_type = TNode;
+  using capacity_type = TCapacity;
+  using normalized_type = WeightedEdge<>;
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+ protected:
+  TCapacity m_capacity;
+
+// =====================================================================================================================
+// Constructor, Destructor, Operators
+
+ public:
+  explicit CapacityEdge(TNode _first, TNode _second, TCapacity capacity);
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+  TCapacity capacity() const;
+  void capacity(TCapacity &&weight);
+
+// =====================================================================================================================
+// ObjectBase interface
+
+ public:
+  EdgeBase *clone() const override;
+
+  EdgeBase *plunder() &&override;
+
+  int compare(const object::ObjectBase &other) const override;
+
+  virtual int compare(const CapacityEdge &other) const;
+
+  object::ObjectBase *inc() &&override;
+
+  void operator>>(std::ostream &ostream) const override;
+
+  explicit operator std::string() const override;
+
+// =====================================================================================================================
+ public:
+
+  virtual std::string name() const;
+
+// ---------------------------------------------------------------------------------------------------------------------
+};
+// =====================================================================================================================
+
+template<typename TNode, typename TCapacity>
+CapacityEdge<TNode, TCapacity>::CapacityEdge(TNode _first, TNode _second, TCapacity capacity)
+    : ext::pair<TNode, TNode>(_first, _second), m_capacity(capacity) {
+
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode, typename TCapacity>
+TCapacity CapacityEdge<TNode, TCapacity>::capacity() const {
+  return m_capacity;
+}
+
+template<typename TNode, typename TCapacity>
+void CapacityEdge<TNode, TCapacity>::capacity(TCapacity &&capacity) {
+  m_capacity = std::forward<TCapacity>(capacity);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode, typename TCapacity>
+std::string CapacityEdge<TNode, TCapacity>::name() const {
+  return "CapacityEdge";
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode, typename TCapacity>
+EdgeBase *CapacityEdge<TNode, TCapacity>::clone() const {
+  return new CapacityEdge(*this);
+}
+
+template<typename TNode, typename TCapacity>
+EdgeBase *CapacityEdge<TNode, TCapacity>::plunder() &&{
+  return new CapacityEdge(std::move(*this));
+}
+
+template<typename TNode, typename TCapacity>
+int CapacityEdge<TNode, TCapacity>::compare(const object::ObjectBase &other) const {
+  if (ext::type_index(typeid(*this)) == ext::type_index(typeid(other))) return this->compare((decltype(*this)) other);
+  return ext::type_index(typeid(*this)) - ext::type_index(typeid(other));
+}
+
+template<typename TNode, typename TCapacity>
+int CapacityEdge<TNode, TCapacity>::compare(const CapacityEdge &other) const {
+  auto one = ext::tie(this->first, this->second, m_capacity);
+  auto two = ext::tie(other.first, other.second, other.m_capacity);
+
+  static ext::compare<decltype(one)> comp;
+
+  return comp(one, two);
+}
+
+template<typename TNode, typename TCapacity>
+object::ObjectBase *CapacityEdge<TNode, TCapacity>::inc() &&{
+  return new object::UniqueObject(object::Object(std::move(*this)), primitive::Integer(0));
+}
+
+template<typename TNode, typename TCapacity>
+void CapacityEdge<TNode, TCapacity>::operator>>(std::ostream &ostream) const {
+  ostream << "(" << name() << "(first=" << this->first << ", second=" << this->second << ", weight="
+          << m_capacity << "))";
+}
+
+template<typename TNode, typename TCapacity>
+CapacityEdge<TNode, TCapacity>::operator std::string() const {
+  std::stringstream ss;
+  ss << "(" << name() << "(first=" << this->first << ", second=" << this->second << ", weight="
+     << m_capacity << "))";
+  return std::move(ss).str();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+} // namespace edge
+
+// =====================================================================================================================
+
+
+#endif //ALIB2_CAPACITYEDGE_HPP
diff --git a/alib2graph_data/src/edge/weighted/WeightedEdge.cpp b/alib2graph_data/src/edge/weighted/WeightedEdge.cpp
new file mode 100644
index 0000000000..5bc22c698d
--- /dev/null
+++ b/alib2graph_data/src/edge/weighted/WeightedEdge.cpp
@@ -0,0 +1,18 @@
+// WeightedEdge.cpp
+//
+//     Created on: 04. 03. 2018
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+
+#include "WeightedEdge.hpp"
+#include <registration/ValuePrinterRegistration.hpp>
+
+namespace {
+
+static auto valuePrinter = registration::ValuePrinterRegister<edge::WeightedEdge<> >();
+
+}
diff --git a/alib2graph_data/src/edge/weighted/WeightedEdge.hpp b/alib2graph_data/src/edge/weighted/WeightedEdge.hpp
new file mode 100644
index 0000000000..6050955c87
--- /dev/null
+++ b/alib2graph_data/src/edge/weighted/WeightedEdge.hpp
@@ -0,0 +1,153 @@
+// WeightedEdge.hpp
+//
+//     Created on: 17. 12. 2017
+//         Author: Jan Uhlik
+//    Modified by:
+//
+// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
+// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
+
+#ifndef ALIB2_WEIGHTEDEDGE_HPP
+#define ALIB2_WEIGHTEDEDGE_HPP
+
+#include <ostream>
+#include <alib/pair>
+#include <object/UniqueObject.h>
+#include <object/Object.h>
+#include <alib/tuple>
+
+#include <edge/EdgeFeatures.hpp>
+#include <edge/EdgeBase.hpp>
+
+namespace edge {
+
+template<typename TNode, typename TWeight>
+class WeightedEdge : public ext::pair<TNode, TNode>, public EdgeBase {
+// ---------------------------------------------------------------------------------------------------------------------
+ public:
+  using node_type = TNode;
+  using weight_type = TWeight;
+  using normalized_type = WeightedEdge<>;
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+ protected:
+  TWeight m_weight;
+
+// =====================================================================================================================
+// Constructor, Destructor, Operators
+
+ public:
+  explicit WeightedEdge(TNode _first, TNode _second, TWeight weight);
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+  TWeight weight() const;
+  void weight(TWeight &&weight);
+
+// =====================================================================================================================
+// ObjectBase interface
+
+ public:
+  EdgeBase *clone() const override;
+
+  EdgeBase *plunder() &&override;
+
+  int compare(const object::ObjectBase &other) const override;
+
+  virtual int compare(const WeightedEdge &other) const;
+
+  object::ObjectBase *inc() &&override;
+
+  void operator>>(std::ostream &ostream) const override;
+
+  explicit operator std::string() const override;
+
+// =====================================================================================================================
+ public:
+
+  virtual std::string name() const;
+
+// ---------------------------------------------------------------------------------------------------------------------
+};
+// =====================================================================================================================
+
+template<typename TNode, typename TWeight>
+WeightedEdge<TNode, TWeight>::WeightedEdge(TNode _first, TNode _second, TWeight weight)
+    : ext::pair<TNode, TNode>(_first, _second), m_weight(weight) {
+
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode, typename TWeight>
+TWeight WeightedEdge<TNode, TWeight>::weight() const {
+  return m_weight;
+}
+
+template<typename TNode, typename TWeight>
+void WeightedEdge<TNode, TWeight>::weight(TWeight &&weight) {
+  m_weight = std::forward<TWeight>(weight);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode, typename TWeight>
+std::string WeightedEdge<TNode, TWeight>::name() const {
+  return "WeightedEdge";
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+template<typename TNode, typename TWeight>
+EdgeBase *WeightedEdge<TNode, TWeight>::clone() const {
+  return new WeightedEdge(*this);
+}
+
+template<typename TNode, typename TWeight>
+EdgeBase *WeightedEdge<TNode, TWeight>::plunder() &&{
+  return new WeightedEdge(std::move(*this));
+}
+
+template<typename TNode, typename TWeight>
+int WeightedEdge<TNode, TWeight>::compare(const object::ObjectBase &other) const {
+  if (ext::type_index(typeid(*this)) == ext::type_index(typeid(other))) return this->compare((decltype(*this)) other);
+  return ext::type_index(typeid(*this)) - ext::type_index(typeid(other));
+}
+
+template<typename TNode, typename TWeight>
+int WeightedEdge<TNode, TWeight>::compare(const WeightedEdge &other) const {
+  auto one = ext::tie(this->first, this->second, m_weight);
+  auto two = ext::tie(other.first, other.second, other.m_weight);
+
+  static ext::compare<decltype(one)> comp;
+
+  return comp(one, two);
+}
+
+template<typename TNode, typename TWeight>
+object::ObjectBase *WeightedEdge<TNode, TWeight>::inc() &&{
+  return new object::UniqueObject(object::Object(std::move(*this)), primitive::Integer(0));
+}
+
+template<typename TNode, typename TWeight>
+void WeightedEdge<TNode, TWeight>::operator>>(std::ostream &ostream) const {
+  ostream << "(" << name() << "(first=" << this->first << ", second=" << this->second << ", weight="
+          << m_weight << "))";
+}
+
+template<typename TNode, typename TWeight>
+WeightedEdge<TNode, TWeight>::operator std::string() const {
+  std::stringstream ss;
+  ss << "(" << name() << "(first=" << this->first << ", second=" << this->second << ", weight="
+     << m_weight << "))";
+  return std::move(ss).str();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+} // namespace edge
+
+// =====================================================================================================================
+
+#endif //ALIB2_WEIGHTEDEDGE_HPP
-- 
GitLab