Skip to content

Instantly share code, notes, and snippets.

@tforgione
Last active December 8, 2016 14:32
Show Gist options
  • Save tforgione/2c894b3d66e4f97f1409daf2fef1fdb6 to your computer and use it in GitHub Desktop.
Save tforgione/2c894b3d66e4f97f1409daf2fef1fdb6 to your computer and use it in GitHub Desktop.
A graph with smart pointers
#include <memory>
#include <vector>
#include <iostream>
template <typename T>
class Node
{
public:
T value;
std::vector<std::weak_ptr<Node<T>>> neighbours;
Node(T value) : value{value}, neighbours{} { std::cout << "Node(" << value << ")" << std::endl; };
~Node() { std::cout << "~Node(" << value << ")" << std::endl; }
};
template<typename T>
class Graph : public std::vector<std::shared_ptr<Node<T>>>
{
public:
std::weak_ptr<Node<T>> get(std::size_t i)
{
auto ret = std::weak_ptr<Node<T>>{};
ret = std::vector<std::shared_ptr<Node<T>>>::operator[](i);
return ret;
}
};
int main(int argc, char *argv[])
{
// Creates a graph with 2 nodes
Graph<int> g;
g.emplace_back(std::make_shared<Node<int>>(0));
g.emplace_back(std::make_shared<Node<int>>(1));
// Sets the edges of the graph (we have a loop here)
g[0]->neighbours.emplace_back(g.get(1));
g[1]->neighbours.emplace_back(g.get(0));
// Start in the graph
auto ptr = g.get(0);
// Move around in the graph, and print position
std::cout << ptr.lock()->value << std::endl;
ptr = ptr.lock()->neighbours[0];
std::cout << ptr.lock()->value << std::endl;
ptr = ptr.lock()->neighbours[0];
std::cout << ptr.lock()->value << std::endl;
ptr = ptr.lock()->neighbours[0];
std::cout << ptr.lock()->value << std::endl;
ptr = ptr.lock()->neighbours[0];
std::cout << ptr.lock()->value << std::endl;
ptr = ptr.lock()->neighbours[0];
std::cout << ptr.lock()->value << std::endl;
// Free the memory : C++ is magic
return 0;
}
SOURCES = graph.cpp node.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: graph node
%.o: %.cpp
$(CXX) -std=c++14 -o $@ -c $< -Wall
graph: graph.o
$(CXX) -std=c++14 -o graph graph.o -Wall
node: node.o
$(CXX) -std=c++14 -o node node.o -Wall
clean:
rm -rf $(OBJECTS)
superclean: clean
rm -rf graph node
#include <memory>
#include <vector>
#include <iostream>
#include <exception>
template <typename T>
class Node
{
class NoSuchNeighbourException : public std::exception {
const char* what() const noexcept {
return "There is no such neighbour in your graph";
}
};
public:
T value;
void add_existing_neighbour(std::weak_ptr<Node<T>> neighbour) {
neighbours.emplace_back(neighbour);
}
std::weak_ptr<Node<T>> add_new_neighbour(T neighbour) {
neighbours_owned.emplace_back(std::make_shared<Node<T>>(neighbour));
return std::weak_ptr<Node<T>>{} = neighbours_owned.back();
}
std::weak_ptr<Node<T>> operator[](std::size_t i) {
if (i < neighbours_owned.size()) {
return neighbours_owned[i];
} else {
i -= neighbours_owned.size();
if (i < neighbours.size()) {
return neighbours[i];
} else {
throw NoSuchNeighbourException{};
}
}
}
Node(T value) : value{value}, neighbours{} { std::cout << "Node(" << value << ")" << std::endl; };
~Node() { std::cout << "~Node(" << value << ")" << std::endl; }
private:
std::vector<std::shared_ptr<Node<T>>> neighbours_owned;
std::vector<std::weak_ptr<Node<T>>> neighbours;
};
int main(int argc, char *argv[])
{
// Creates a graph with 2 nodes
auto node = std::make_shared<Node<int>>(0);
auto other = node->add_new_neighbour(1);
other.lock()->add_existing_neighbour(node);
// Start in the graph
auto ptr = std::weak_ptr<Node<int>>{};
ptr = node;
// Move around in the graph, and print position
std::cout << "ptr = " << ptr.lock()->value << std::endl;
ptr = (*ptr.lock())[0];
std::cout << "ptr = " << ptr.lock()->value << std::endl;
ptr = (*ptr.lock())[0];
std::cout << "ptr = " << ptr.lock()->value << std::endl;
ptr = (*ptr.lock())[0];
std::cout << "ptr = " << ptr.lock()->value << std::endl;
ptr = (*ptr.lock())[0];
std::cout << "ptr = " << ptr.lock()->value << std::endl;
ptr = (*ptr.lock())[0];
std::cout << "ptr = " << ptr.lock()->value << std::endl;
// Free the memory : C++ is magic
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment