Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Created September 22, 2014 23:44
Show Gist options
  • Save dgodfrey206/f42956141f4fc6027825 to your computer and use it in GitHub Desktop.
Save dgodfrey206/f42956141f4fc6027825 to your computer and use it in GitHub Desktop.
A simple deque implementation
#include <iostream>
#include <stdexcept>
template <typename Item>
class Deque
{
class iterator;
class node;
public:
Deque() = default;
bool isEmpty();
int size();
void addFirst(Item item);
Item removeFirst();
Item removeLast();
iterator begin();
iterator end();
private:
node* head{nullptr};
node* tail{nullptr};
int count{0};
void increase_count() { ++count; }
void decrease_count()
{
--count;
if (isEmpty())
tail = head;
}
};
template <typename Item>
bool Deque<Item>::isEmpty()
{
return !head || count == 0;
}
template <typename Item>
void Deque<Item>::addFirst(Item item)
{
node* newHead = new node(item);
if (isEmpty())
{
head = newHead;
tail = head;
}
else
{
newHead->next = head;
head = newHead;
if (tail == nullptr) tail = newHead;
}
increase_count();
tail->next = nullptr;
}
template <typename Item>
Item Deque<Item>::removeFirst()
{
if (isEmpty())
{
throw std::out_of_range("Deque is empty.");
}
Item oldValue = head->data;
node* oldNode = head;
head->next = head->next->next;
delete oldNode;
decrease_count();
return oldValue;
}
template <typename Item>
Item Deque<Item>::removeLast()
{
if (isEmpty())
{
throw std::out_of_range("Deque is empty.");
}
Item oldValue = tail->data;
node* oneBefore = head;
if (oneBefore->next == nullptr)
{
delete oneBefore;
head = nullptr;
tail = nullptr;
}
else
{
while (oneBefore->next != nullptr)
oneBefore = oneBefore->next;
delete oneBefore->next;
tail = oneBefore;
}
decrease_count();
return oldValue;
}
template <typename Item>
typename Deque<Item>::iterator Deque<Item>::begin()
{
return iterator(head);
}
template <typename Item>
typename Deque<Item>::iterator Deque<Item>::end()
{
return iterator();
}
template <typename Item>
class Deque<Item>::iterator
{
public:
iterator() : iter(nullptr) { }
iterator(node* first) : iter(first) { }
Item& operator*() { return iter->data; }
Item const& operator*() const { return iter->data; }
iterator& operator++() { update(); return *this; }
iterator operator++(int) { iterator copy(*this); ++*this; return copy; }
friend bool operator==(typename Deque<Item>::iterator const& lhs, typename Deque<Item>::iterator const& rhs)
{ return lhs.iter == rhs.iter; }
friend bool operator!=(typename Deque<Item>::iterator const& lhs, typename Deque<Item>::iterator const& rhs)
{ return !(lhs == rhs); }
private:
node* iter;
void update() { iter = iter->next; }
};
template <typename Item>
class Deque<Item>::node
{
Item data;
node* next;
friend class Deque<Item>;
friend class Deque<Item>::iterator;
public:
node(Item item) : data(item) { }
};
int main()
{
Deque<int> deque;
deque.addFirst(3);
deque.addFirst(10);
deque.addFirst(35);
for (auto& x : deque)
{
std::cout << x << " ";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment