Skip to content

Commit

Permalink
Convert raw pointers to smart pointers (#316)
Browse files Browse the repository at this point in the history
* Change all the raw pointers in the library to smart pointers

* Rewrite tests to use smart pointers

* Finish converting tests to smart pointers

* Add setter for nodes in Edge nodePair

* Fix addition of edges and construction of adjacency matrix

* Add overloads of algorithms which take raw pointers to mantain interface

* Fix typos in tests

* Change dynamic_casts into dynamic_pointer_casts

* Decrease the number of random edges and nodes in RW and partition tests

* Add overload of equality operators and hash functions for pointers of nodes

* Implement new hash functions for pointers of nodes and edges

* Increase number of nodes and edges in partition and RW tests

* Fix typo

* Use shared pointers in random node/edge generators

* Convert pointers in TransitiveReductionTest.cpp

* Add overload of addEdge for raw pointers

* Fix typo

* Fix edge insertion in FloydWarshall benchmark

* Fix typo in benchmark

* Remove all the calls to new in the tests

* Fix typo in benchmark FloydWarshall

Fix typo in benchmark FloydWarshall

* Conversion of example codes
  • Loading branch information
sbaldu committed Jun 1, 2023
1 parent 5fc8449 commit 4569d22
Show file tree
Hide file tree
Showing 55 changed files with 2,182 additions and 1,327 deletions.
32 changes: 18 additions & 14 deletions benchmark/FloydWarshall_BM.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#include <benchmark/benchmark.h>
#include <Edge/DirectedWeightedEdge.hpp>
#include <memory>

#include "CXXGraph.hpp"
#include "Utilities.hpp"

using std::make_shared;

// https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm#Example
static void BM_FWDirected(benchmark::State &state) {
CXXGraph::Node<int> node1("1", 1);
Expand All @@ -17,11 +21,11 @@ static void BM_FWDirected(benchmark::State &state) {
CXXGraph::DirectedWeightedEdge<int> edge5(3, node2, node3, 3);

CXXGraph::T_EdgeSet<int> edgeSet;
edgeSet.insert(&edge1);
edgeSet.insert(&edge2);
edgeSet.insert(&edge3);
edgeSet.insert(&edge4);
edgeSet.insert(&edge5);
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge1));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge2));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge3));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge4));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge5));

CXXGraph::Graph<int> graph(edgeSet);
for (auto _ : state) {
Expand All @@ -39,9 +43,9 @@ static void BM_FWNegCycle(benchmark::State &state) {
CXXGraph::DirectedWeightedEdge<int> edge2(2, node1, node2, 3);
CXXGraph::DirectedWeightedEdge<int> edge3(3, node2, node0, -7);
CXXGraph::T_EdgeSet<int> edgeSet;
edgeSet.insert(&edge1);
edgeSet.insert(&edge2);
edgeSet.insert(&edge3);
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge1));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge2));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge3));
CXXGraph::Graph<int> graph(edgeSet);
for (auto _ : state) {
CXXGraph::FWResult res = graph.floydWarshall();
Expand All @@ -59,9 +63,9 @@ static void BM_FWUndirectedWeighted(benchmark::State &state) {
CXXGraph::DirectedWeightedEdge<int> edge2(2, node2, node3, 1);
CXXGraph::UndirectedWeightedEdge<int> edge3(3, node1, node3, 6);
CXXGraph::T_EdgeSet<int> edgeSet;
edgeSet.insert(&edge1);
edgeSet.insert(&edge2);
edgeSet.insert(&edge3);
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge1));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge2));
edgeSet.insert(make_shared<CXXGraph::UndirectedWeightedEdge<int>>(edge3));
CXXGraph::Graph<int> graph(edgeSet);
for (auto _ : state) {
CXXGraph::FWResult res = graph.floydWarshall();
Expand All @@ -79,9 +83,9 @@ static void BM_FWNoWeighted(benchmark::State &state) {
CXXGraph::DirectedWeightedEdge<int> edge2(2, node2, node3, 1);
CXXGraph::DirectedEdge<int> edge3(3, node1, node3);
CXXGraph::T_EdgeSet<int> edgeSet;
edgeSet.insert(&edge1);
edgeSet.insert(&edge2);
edgeSet.insert(&edge3);
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge1));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge2));
edgeSet.insert(make_shared<CXXGraph::DirectedEdge<int>>(edge3));
CXXGraph::Graph<int> graph(edgeSet);
for (auto _ : state) {
CXXGraph::FWResult res = graph.floydWarshall();
Expand Down
15 changes: 9 additions & 6 deletions examples/DialExample/dial_example.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#include <math.h>
#include <memory>

#include <CXXGraph.hpp>

using std::make_shared;

typedef struct euclid_point {
double x;
double y;
Expand Down Expand Up @@ -49,11 +52,11 @@ int main() {
points_vector.at(node2.getData())));

CXXGraph::T_EdgeSet<int> edgeSet;
edgeSet.insert(&edge1);
edgeSet.insert(&edge2);
edgeSet.insert(&edge3);
edgeSet.insert(&edge4);
edgeSet.insert(&edge5);
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge1));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge2));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge3));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge4));
edgeSet.insert(make_shared<CXXGraph::DirectedWeightedEdge<int>>(edge5));

// Can print out the edges for debugging
std::cout << edge1 << "\n";
Expand All @@ -68,4 +71,4 @@ int main() {
std::cout << "Dial Result: " << res.minDistanceMap.at(node3.getId()) << ", "
<< res.success << "\n";
return 0;
}
}
14 changes: 9 additions & 5 deletions examples/DijkstraExample/dijkstra_example.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include <CXXGraph.hpp>

#include <memory>

using std::make_shared;

int main() {
CXXGraph::Node<int> node0("0", 0);
CXXGraph::Node<int> node1("1", 1);
Expand All @@ -12,10 +16,10 @@ int main() {
CXXGraph::UndirectedWeightedEdge<int> edge4(4, node0, node3, 1.0);

CXXGraph::T_EdgeSet<int> edgeSet;
edgeSet.insert(&edge1);
edgeSet.insert(&edge2);
edgeSet.insert(&edge3);
edgeSet.insert(&edge4);
edgeSet.insert(make_shared<CXXGraph::UndirectedWeightedEdge<int>>(edge1));
edgeSet.insert(make_shared<CXXGraph::UndirectedWeightedEdge<int>>(edge2));
edgeSet.insert(make_shared<CXXGraph::UndirectedWeightedEdge<int>>(edge3));
edgeSet.insert(make_shared<CXXGraph::UndirectedWeightedEdge<int>>(edge4));

// Can print out the edges for debugging
std::cout << edge1 << "\n";
Expand All @@ -29,4 +33,4 @@ int main() {
std::cout << "Dijkstra Result: " << res.result << "\n";

return 0;
}
}
25 changes: 24 additions & 1 deletion include/Edge/DirectedEdge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
#include "Edge.hpp"

namespace CXXGraph {
// Smart pointers alias
template <typename T>
using unique = std::unique_ptr<T>;
template <typename T>
using shared= std::shared_ptr<T>;

using std::make_unique;
using std::make_shared;

template <typename T>
class UndirectedEdge;

Expand All @@ -38,8 +47,12 @@ class DirectedEdge : public Edge<T> {
public:
DirectedEdge(const unsigned long id, const Node<T> &node1,
const Node<T> &node2);
DirectedEdge(const unsigned long id, shared<const Node<T>> node1,
shared<const Node<T>> node2);
DirectedEdge(const unsigned long id,
const std::pair<const Node<T> *, const Node<T> *> &nodepair);
DirectedEdge(const unsigned long id,
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &nodepair);
DirectedEdge(const Edge<T> &edge);
virtual ~DirectedEdge() = default;
const Node<T> &getFrom() const;
Expand All @@ -60,12 +73,22 @@ DirectedEdge<T>::DirectedEdge(const unsigned long id, const Node<T> &node1,
const Node<T> &node2)
: Edge<T>(id, node1, node2) {}

template <typename T>
DirectedEdge<T>::DirectedEdge(const unsigned long id, shared<const Node<T>> node1,
shared<const Node<T>> node2) : Edge<T>(id, node1, node2) {}

template <typename T>
DirectedEdge<T>::DirectedEdge(
const unsigned long id,
const std::pair<const Node<T> *, const Node<T> *> &nodepair)
: Edge<T>(id, nodepair) {}

template <typename T>
DirectedEdge<T>::DirectedEdge(
const unsigned long id,
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &nodepair)
: Edge<T>(id, nodepair) {}

template <typename T>
DirectedEdge<T>::DirectedEdge(const Edge<T> &edge)
: DirectedEdge(edge.getId(), *(edge.getNodePair().first),
Expand Down Expand Up @@ -99,4 +122,4 @@ std::ostream &operator<<(std::ostream &os, const DirectedEdge<T> &edge) {
}
} // namespace CXXGraph

#endif // __CXXGRAPH_DIRECTEDEDGE_H__
#endif // __CXXGRAPH_DIRECTEDEDGE_H__
31 changes: 30 additions & 1 deletion include/Edge/DirectedWeightedEdge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
#include "Weighted.hpp"

namespace CXXGraph {
// Smart pointers alias
template <typename T>
using unique = std::unique_ptr<T>;
template <typename T>
using shared= std::shared_ptr<T>;

using std::make_unique;
using std::make_shared;

// Foward Declaration
template <typename T>
class UndirectedWeightedEdge;
Expand All @@ -41,10 +50,16 @@ class DirectedWeightedEdge : public DirectedEdge<T>, public Weighted {
public:
DirectedWeightedEdge(const unsigned long id, const Node<T> &node1,
const Node<T> &node2, const double weight);
DirectedWeightedEdge(const unsigned long id, shared<const Node<T>> node1,
shared<const Node<T>> node2, const double weight);
DirectedWeightedEdge(
const unsigned long id,
const std::pair<const Node<T> *, const Node<T> *> &nodepair,
const double weight);
DirectedWeightedEdge(
const unsigned long id,
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &nodepair,
const double weight);
DirectedWeightedEdge(const DirectedEdge<T> &edge, const double weight);
DirectedWeightedEdge(const Edge<T> &edge, const double weight);
DirectedWeightedEdge(const DirectedEdge<T> &edge);
Expand All @@ -69,13 +84,27 @@ DirectedWeightedEdge<T>::DirectedWeightedEdge(const unsigned long id,
const double weight)
: DirectedEdge<T>(id, node1, node2), Weighted(weight) {}

template <typename T>
DirectedWeightedEdge<T>::DirectedWeightedEdge(const unsigned long id,
shared<const Node<T>> node1,
shared<const Node<T>> node2,
const double weight)
: DirectedEdge<T>(id, node1, node2), Weighted(weight) {}

template <typename T>
DirectedWeightedEdge<T>::DirectedWeightedEdge(
const unsigned long id,
const std::pair<const Node<T> *, const Node<T> *> &nodepair,
const double weight)
: DirectedEdge<T>(id, nodepair), Weighted(weight) {}

template <typename T>
DirectedWeightedEdge<T>::DirectedWeightedEdge(
const unsigned long id,
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &nodepair,
const double weight)
: DirectedEdge<T>(id, nodepair), Weighted(weight) {}

template <typename T>
DirectedWeightedEdge<T>::DirectedWeightedEdge(const DirectedEdge<T> &edge,
const double weight)
Expand Down Expand Up @@ -115,4 +144,4 @@ std::ostream &operator<<(std::ostream &os,

} // namespace CXXGraph

#endif // __CXXGRAPH_DIRECTEDWEIGHTEDEDGE_H__
#endif // __CXXGRAPH_DIRECTEDWEIGHTEDEDGE_H__
59 changes: 51 additions & 8 deletions include/Edge/Edge.hpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,22 @@

#pragma once

#include <memory>
#include <optional>
#include <utility>

#include "Node/Node.hpp"

namespace CXXGraph {
// Smart pointers alias
template <typename T>
using unique = std::unique_ptr<T>;
template <typename T>
using shared = std::shared_ptr<T>;

using std::make_unique;
using std::make_shared;

template <typename T>
class Edge;
// ostream operator
Expand All @@ -37,16 +47,21 @@ template <typename T>
class Edge {
private:
unsigned long long id = 0;
std::pair<const Node<T> *, const Node<T> *> nodePair;
std::pair<shared<const Node<T>>, shared<const Node<T>>> nodePair;

public:
Edge(const unsigned long long id, const Node<T> &node1, const Node<T> &node2);
Edge(const unsigned long long id, shared<const Node<T>> node1, shared<const Node<T>> node2);
Edge(const unsigned long long id,
const std::pair<const Node<T> *, const Node<T> *> &nodepair);
Edge(const unsigned long long id,
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &nodepair);
virtual ~Edge() = default;
void setFirstNode(shared<const Node<T>> node);
void setSecondNode(shared<const Node<T>> node);
const unsigned long long &getId() const;
const std::pair<const Node<T> *, const Node<T> *> &getNodePair() const;
const Node<T> *getOtherNode(const Node<T> *node) const;
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &getNodePair() const;
shared<const Node<T>> getOtherNode(shared<const Node<T>> node) const;
virtual const std::optional<bool> isDirected() const;
virtual const std::optional<bool> isWeighted() const;
// operator
Expand All @@ -61,31 +76,59 @@ class Edge {

template <typename T>
Edge<T>::Edge(const unsigned long long id, const Node<T> &node1,
const Node<T> &node2)
: nodePair(&node1, &node2) {
const Node<T> &node2) {
this->nodePair.first = make_shared<const Node<T>>(node1);
this->nodePair.second = make_shared<const Node<T>>(node2);
this->id = id;
}

template <typename T>
Edge<T>::Edge(const unsigned long long id, shared<const Node<T>> node1, shared<const Node<T>> node2) {
this->nodePair.first = node1;
this->nodePair.second = node2;
this->id = id;
}

template <typename T>
Edge<T>::Edge(const unsigned long long id,
const std::pair<const Node<T> *, const Node<T> *> &nodepair) {
this->nodePair.first = make_shared<const Node<T>>(*(nodepair.first));
this->nodePair.second = make_shared<const Node<T>>(*(nodepair.second));
this->id = id;
}

template <typename T>
Edge<T>::Edge(const unsigned long long id,
const std::pair<const Node<T> *, const Node<T> *> &nodepair)
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &nodepair)
: nodePair(nodepair) {
this->id = id;
}

template <typename T>
void Edge<T>::setFirstNode(shared<const Node<T>> node) {
/* this->nodePair = std::make_pair(node, this->nodePair.second); */
this->nodePair.first = node;
}

template <typename T>
void Edge<T>::setSecondNode(shared<const Node<T>> node) {
/* this->nodePair = std::make_pair(this->nodePair.first, node); */
this->nodePair.second = node;
}

template <typename T>
const unsigned long long &Edge<T>::getId() const {
return id;
}

template <typename T>
const std::pair<const Node<T> *, const Node<T> *> &Edge<T>::getNodePair()
const std::pair<shared<const Node<T>>, shared<const Node<T>>> &Edge<T>::getNodePair()
const {
return nodePair;
}

template <typename T>
const Node<T> *Edge<T>::getOtherNode(const Node<T> *node) const {
shared<const Node<T>> Edge<T>::getOtherNode(shared<const Node<T>> node) const {
if (this->getNodePair().first == node) {
return this->getNodePair().second;
} else {
Expand Down
Loading

0 comments on commit 4569d22

Please sign in to comment.