Skip to content

Instantly share code, notes, and snippets.

@cammckinnon
Created July 20, 2012 15:40
Show Gist options
  • Save cammckinnon/3151430 to your computer and use it in GitHub Desktop.
Save cammckinnon/3151430 to your computer and use it in GitHub Desktop.
'smart' pointer 'implementation'
#include <iostream>
#include <string>
using namespace std;
/* START AUTO POINTER IMPLEMENTATION */
class super_wrapped_object {
public:
virtual void refCountDown() = 0;
virtual void refCountUp() = 0;
virtual void release() = 0;
virtual int refCount() = 0;
virtual void* voidObject() const = 0;
};
template <class T>
class wrapped_object : public super_wrapped_object{
public:
int refcount;
T * object;
int refCount() { return refcount; }
void* voidObject() const {
return reinterpret_cast<void*>(object);
}
void refCountDown() {
if (!object) {
return;
}
refcount--;
if (refcount == 0) {
release();
delete this;
}
}
void refCountUp() {
if (!object) {
return;
}
refcount++;
}
void release() {
delete object;
}
wrapped_object(): object(0), refcount(0) {
}
wrapped_object(T * t): object(t), refcount(t ? 1 : 0){}
};
template <class T>
class wrapped_array : public wrapped_object<T> {
public:
void release() {
delete[] this->object;
}
wrapped_array(): wrapped_object<T>() {}
wrapped_array(T* t): wrapped_object<T>(t) {}
};
template <class T>
class auto_ptr{
public:
super_wrapped_object * points_to;
T * pointerValue() const{
return (T*)(points_to ? points_to->voidObject() : 0);
}
void refCountUp() {
if (pointerValue()) {
points_to->refCountUp();
}
}
void refCountDown() {
if (pointerValue()) {
points_to->refCountDown();
}
}
auto_ptr(const auto_ptr<T>& b) {
points_to = b.points_to;
refCountUp();
}
template<class E> explicit auto_ptr(const auto_ptr<E>& b) {
points_to = b.points_to;
refCountUp();
}
explicit auto_ptr(T* p = 0, bool array = false) {
if (p) {
if (array) {
points_to = new wrapped_array<T>(p);
} else {
points_to = new wrapped_object<T>(p);
}
} else {
points_to = 0;
}
}
~auto_ptr() {
refCountDown();
}
template<class E>
auto_ptr<T>& operator= (const auto_ptr<E>& b) {
T * t = (E *)0; // make sure the cast is actually possible
refCountDown();
points_to = b.points_to;
refCountUp();
return *this;
}
auto_ptr<T>& operator= (const auto_ptr<T>& b) {
refCountDown();
points_to = b.points_to;
refCountUp();
return *this;
}
template <class E>
bool operator== (const auto_ptr<E>& b) {
return pointerValue() == b.pointerValue();
}
T& operator* () { return *pointerValue(); }
T* operator-> () { return pointerValue(); }
T* operator-> () const { return pointerValue(); }
T& operator[] (unsigned int i) {
return *(pointerValue() + i);
}
// careful with this!!
T* rawPointer() const{ return pointerValue(); }
operator bool() const {
return (bool)(this->rawPointer());
}
};
template <class T>
auto_ptr<T> auto_array(T * p) {
return auto_ptr<T>(p, true);
}
template <class T>
auto_ptr<T> null() {
return auto_ptr<T>();
}
/* END AUTO POINTER IMPLEMENTATION */
template <class T>
class Node {
public:
T data;
auto_ptr<Node<T> > next;
Node(T data, auto_ptr<Node<T> > next): data(data), next(next) {}
};
template <class T>
class LinkedList {
protected:
unsigned int length;
public:
// initialize with length 0 and first element null
LinkedList(): length(0), first(null<Node<T> >()) {}
// keep a pointer to first node in the list
auto_ptr<Node<T> > first;
// insert a new node into the list
void insert(T data) {
auto_ptr<Node<T> > newNode(new Node<T>(data, first));
first = newNode;
length++;
}
bool inList(T needle) {
auto_ptr<Node<T> > cur;
cur = first;
while (cur) {
if (cur->data == needle) {
return true;
}
cur = cur->next;
}
return true;
}
unsigned int size() { return length; }
// for debugging
void print() const {
auto_ptr<Node<T> > cur;
cur = first;
cout<<": ";
while (cur) {
cout<<cur->data;
cur = cur->next;
if (cur != 0) {
cout<<", ";
}
}
cout<<endl;
}
};
template <class E>
class HashTable {
public:
// used internally
unsigned int length;
auto_ptr<LinkedList<E> > table;
// implement this in a child class
// note: result will be taken mod length
virtual unsigned int hash(E e) = 0;
// constructor
HashTable(): length(23),
table(auto_array(new LinkedList<E>[length])) {}
// utility functions
void insert(E e) {
unsigned int index = hash(e) % length;
this->table[index].insert(e);
}
unsigned int size() {
return length;
}
bool inTable(E needle) {
return table[hash(needle) % length].inList(needle);
}
};
class HashTableA : public HashTable<string> {
public:
unsigned int hash(string s) {
unsigned int sum = 0;
for (int i = 0; i < s.length(); i++) {
sum += (s.at(i) - 'a' + 1);
}
return sum;
}
};
int main() {
auto_ptr<HashTable<string> > table =
auto_ptr<HashTable<string> >(new HashTableA);
table->insert("a");
table->insert("b");
table->insert("c");
table->insert("aa");
table->insert("lol wut");
table->insert("tuw lol");
table->insert("the quick brown fox jumped over the lazy dog");
for (unsigned int i = 0; i < table->size(); i++) {
cout<<i<<" ";
table->table[i].print();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment