Last active
August 29, 2015 14:22
-
-
Save mwhittaker/9c9a658201ab1e934071 to your computer and use it in GitHub Desktop.
C++ Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
# vim | |
################################################################################ | |
*.sw[op] | |
################################################################################ | |
# C++ | |
################################################################################ | |
# Compiled Object files | |
*.slo | |
*.lo | |
*.o | |
*.obj | |
# Precompiled Headers | |
*.gch | |
*.pch | |
# Compiled Dynamic libraries | |
*.so | |
*.dylib | |
*.dll | |
# Fortran module files | |
*.mod | |
# Compiled Static libraries | |
*.lai | |
*.la | |
*.a | |
*.lib | |
# Executables | |
*.exe | |
*.out | |
*.app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <functional> | |
#include <iostream> | |
#include <vector> | |
#include "Foo.h" | |
using namespace std; | |
int Foo::ID = 0; | |
Foo::Foo(int x) : x(new int(x)), id(ID++) { | |
cout << string(id, ' ') << *this << endl; | |
} | |
Foo::Foo(const Foo& other) : x(new int(*other.x)), id(ID++) { | |
cout << string(id, ' ') << other << " -copy-> " << *this << endl; | |
} | |
Foo::Foo(Foo&& other) : x(other.x), id(ID++) { | |
cout << string(id, ' ') << other << " -move-> " << *this << endl; | |
other.x = nullptr; | |
} | |
Foo& Foo::operator=(Foo other) { | |
cout << string(id, ' ') << *this << " = " << other << endl; | |
swap(*this, other); | |
return *this; | |
} | |
Foo::~Foo() { | |
cout << string(id, ' ') << "~" << *this << endl; | |
delete x; | |
} | |
void swap(Foo& a, Foo& b) { | |
cout << "swap" << endl; | |
swap(a.x, b.x); | |
swap(a.id, b.id); | |
} | |
void Foo::reset() { | |
ID = 0; | |
} | |
std::ostream& operator<<(std::ostream& os, const Foo& f) { | |
if (f.x) { | |
os << "Foo(" << *f.x << ")[" << f.id << "]"; | |
} else { | |
os << "Foo(null)[" << f.id << "]"; | |
} | |
return os; | |
} | |
bool operator==(const Foo &a, const Foo &b) { return a.x == b.x; } | |
bool operator!=(const Foo &a, const Foo &b) { return a.x != b.x; } | |
bool operator<=(const Foo &a, const Foo &b) { return a.x <= b.x; } | |
bool operator>=(const Foo &a, const Foo &b) { return a.x >= b.x; } | |
bool operator< (const Foo &a, const Foo &b) { return a.x < b.x; } | |
bool operator> (const Foo &a, const Foo &b) { return a.x > b.x; } | |
void take(Foo f) { | |
(void) f; | |
} | |
void borrow(Foo& f) { | |
(void) f; | |
} | |
void move(Foo&& f) { | |
(void) f; | |
} | |
void take_vector(Foo f) { | |
vector<Foo> v{f}; | |
(void) v; | |
} | |
void borrow_vector(Foo& f) { | |
vector<Foo> v{f}; | |
(void) v; | |
} | |
void move_vector(Foo&& f) { | |
vector<Foo> v{std::move(f)}; | |
(void) v; | |
} | |
int main() { | |
auto f1 = []() { | |
Foo f(10); | |
}; | |
auto f2 = []() { | |
Foo f1(10); | |
Foo f2(20); | |
}; | |
auto f3 = []() { | |
Foo f1(10); | |
Foo f2(f1); | |
}; | |
auto f4 = []() { | |
Foo f2(Foo(10)); | |
}; | |
auto f5 = []() { | |
Foo f1(10); | |
Foo f2(std::move(f1)); | |
}; | |
auto f6 = []() { | |
Foo f(10); | |
take(f); | |
}; | |
auto f7 = []() { | |
Foo f(10); | |
borrow(f); | |
}; | |
auto f8 = []() { | |
Foo f(10); | |
move(std::move(f)); | |
}; | |
auto f9 = []() { | |
Foo f(10); | |
take_vector(f); | |
}; | |
auto f10 = []() { | |
Foo f(10); | |
borrow_vector(f); | |
}; | |
auto f11 = []() { | |
Foo f(10); | |
move_vector(std::move(f)); | |
}; | |
vector<function<void()>> fs{ | |
f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, | |
f11, | |
}; | |
int i = 1; | |
for (auto f : fs) { | |
cout << "// f" << i++ << endl; | |
f(); | |
cout << endl; | |
Foo::reset(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __FOO_H__ | |
#define __FOO_H__ | |
#include <iostream> | |
class Foo { | |
public: | |
Foo(int x); // 1. constructor | |
Foo(const Foo& other); // 2. copy constructor | |
Foo(Foo&& other); // 3. move constructor | |
Foo& operator=(Foo other); // 4. assignment constructor | |
~Foo(); // destructor | |
friend void swap(Foo& a, Foo& b); // swap | |
static void reset(); | |
friend std::ostream& operator<<(std::ostream& os, const Foo& f); | |
friend bool operator==(const Foo &a, const Foo &b); | |
friend bool operator!=(const Foo &a, const Foo &b); | |
friend bool operator<=(const Foo &a, const Foo &b); | |
friend bool operator>=(const Foo &a, const Foo &b); | |
friend bool operator< (const Foo &a, const Foo &b); | |
friend bool operator> (const Foo &a, const Foo &b); | |
private: | |
static int ID; | |
int *x; | |
int id; | |
}; | |
#endif // __FOO_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <sstream> | |
#include <cstdio> | |
#include "Graph.h" | |
using namespace std; | |
int main() { | |
Graph<int> g; | |
// add nodes | |
for (int i = 0; i < 10; ++i) { | |
g.add_node(i); | |
} | |
// add edges | |
for (int i = 0; i < 10; ++i) { | |
for (int j = i + 1; j < 10; ++j) { | |
g.add_edge(i, j); | |
} | |
} | |
cout << g << endl; | |
// cyclic | |
cout << "g is cyclic? " << boolalpha << g.cyclic() << endl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __GRAPH_G__ | |
#define __GRAPH_G__ | |
#include <map> | |
#include <set> | |
#include <iostream> | |
template <typename T> | |
class Graph { | |
public: | |
Graph() : adj_list() {} | |
void add_node(T u) { | |
if (adj_list.count(u) == 0) { | |
adj_list[u] = std::set<T>(); | |
} | |
} | |
void add_edge(T u, T v) { | |
add_node(u); | |
add_node(v); | |
adj_list[u].insert(v); | |
} | |
bool cyclic() const { | |
for (const auto& p : adj_list) { | |
if (cyclic(p.first)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
template <typename U> | |
friend std::ostream& operator<<(std::ostream& os, const Graph<U>& g); | |
private: | |
std::map<T, std::set<T>> adj_list; | |
bool cyclic(const T& root) const { | |
std::set<T> seen; | |
std::set<T> frontier{root}; | |
while (frontier.size() != 0) { | |
T u = *frontier.begin(); | |
frontier.erase(u); | |
if (seen.count(u)) { | |
return true; | |
} | |
seen.insert(u); | |
for (auto& neighbor : adj_list.at(u)) { | |
frontier.insert(neighbor); | |
} | |
} | |
return false; | |
} | |
}; | |
template <typename U> | |
std::ostream& operator<<(std::ostream& os, const Graph<U>& g) { | |
for (const auto& p : g.adj_list) { | |
os << p.first << ": "; | |
for (const auto& x : p.second) { | |
os << x << " "; | |
} | |
os << std::endl; | |
} | |
return os; | |
} | |
#endif // __GRAPH_G__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
int main() { | |
std::cout << "hello, world!" << std::endl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CPPFLAGS = -O0 -Wall -Wextra -pedantic -g -std=c++11 -pthread | |
SRCS = $(wildcard *.cc) | |
HEADERS = $(wildcard *.h) | |
BINS = $(SRCS:.cc=) | |
all: $(BINS) | |
%: %.cc %.h | |
clang++ $< -o $@ $(CPPFLAGS) | |
clean: | |
$(RM) $(BINS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "point.h" | |
#include <iostream> | |
#include <cmath> | |
using namespace std; | |
Point::Point() : Point(0.0, 0.0) {} | |
Point::Point(double x, double y) { | |
this->x = x; | |
this->y = y; | |
} | |
double Point::distance(const Point& p) { | |
double dx = abs(x - p.x); | |
double dy = abs(y - p.y); | |
return sqrt((dx * dx) + (dy * dy)); | |
} | |
ostream& operator<<(ostream& stream, const Point& p) { | |
return stream << "(" << p.x << ", " << p.y << ")"; | |
} | |
int main() { | |
Point a(1.0, 2.0); | |
Point b(4.0, 6.0); | |
cout << a << endl; | |
cout << b << endl; | |
cout << a.distance(b) << endl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __POINT_H__ | |
#define __POINT_H__ | |
#include <iostream> | |
class Point { | |
public: | |
Point(); | |
Point(double x, double y); | |
double distance(const Point& p); | |
friend std::ostream& operator<<(std::ostream& stream, const Point& p); | |
private: | |
double x; | |
double y; | |
}; | |
#endif // __POINT_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <memory> | |
using namespace std; | |
int main() { | |
{ | |
string *s = new string; | |
cout << *s << endl; | |
delete s; | |
} | |
{ | |
string *s = new string(10, 'a'); | |
cout << *s << endl; | |
delete s; | |
} | |
{ | |
unique_ptr<string> p(new string); | |
cout << *p << endl; | |
} | |
{ | |
unique_ptr<string> p(new string(10, 'a')); | |
cout << *p << endl; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cassert> | |
#include "tree.h" | |
using namespace std; | |
int main() { | |
Tree<int> t; | |
assert (t.size() == 0); | |
for (int i = 0; i < 10; ++i) { | |
t.add(i); | |
} | |
assert (t.size() == 10); | |
for (int i = 0; i < 10; ++i) { | |
assert (t.contains(i)); | |
} | |
for (int i = 10; i < 20; ++i) { | |
assert (!t.contains(i)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __TREE_H__ | |
#define __TREE_H__ | |
#include <memory> | |
template <typename T> | |
class Node { | |
public: | |
T x; | |
std::unique_ptr<Node<T>> left; | |
std::unique_ptr<Node<T>> right; | |
Node(T x) : Node(x, nullptr, nullptr) {} | |
Node(T x, std::unique_ptr<Node<T>> left, std::unique_ptr<Node<T>> right) { | |
this->x = x; | |
this->left = std::move(left); | |
this->right = std::move(right); | |
} | |
void add(T y) { | |
if (y < x) { | |
if (left == nullptr) { | |
left = std::unique_ptr<Node<T>>(new Node<T>(y)); | |
} else { | |
left->add(y); | |
} | |
} else if (y > x) { | |
if (right == nullptr) { | |
right = std::unique_ptr<Node<T>>(new Node<T>(y)); | |
} else { | |
right->add(y); | |
} | |
} else /* x == y */ { | |
// do nothing | |
} | |
} | |
uint size() const { | |
uint size_left = left == nullptr ? 0 : left->size(); | |
uint size_right = right == nullptr ? 0 : right->size(); | |
return 1 + size_left + size_right; | |
} | |
bool contains(const T& y) const { | |
if (y < x) { | |
return left != nullptr && left->contains(y); | |
} else if (y > x) { | |
return right != nullptr && right->contains(y); | |
} else { | |
return true; | |
} | |
} | |
}; | |
template <typename T> | |
class Tree { | |
public: | |
Tree() { | |
root = nullptr; | |
} | |
uint size() const { | |
return root == nullptr ? 0 : root->size(); | |
} | |
void add(T x) { | |
if (root == nullptr) { | |
root = std::unique_ptr<Node<T>>(new Node<T>(x)); | |
} else { | |
root->add(x); | |
} | |
} | |
bool contains(const T& x) const { | |
return root != nullptr && root->contains(x); | |
} | |
private: | |
std::unique_ptr<Node<T>> root; | |
}; | |
#endif // __TREE_H__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment