Last active
August 29, 2015 14:08
-
-
Save SeijiEmery/0fa5eb7619df704c4546 to your computer and use it in GitHub Desktop.
Stack implementation
This file contains hidden or 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
// Copyright (c) 2014, Seiji Emery | |
// All rights reserved. | |
#ifndef __STACK_HPP__ | |
#define __STACK_HPP__ | |
#include <algorithm> | |
#include <cassert> | |
template <typename T> | |
class Buffer { | |
public: | |
Buffer () : m_size(0), m_buffer(nullptr) {} | |
Buffer (size_t size) | |
: m_size(0), m_buffer(nullptr) { resize(size); } | |
Buffer (const Buffer<T> &other) | |
: m_size(other.m_size), m_buffer(new T [other.m_size]) | |
{ | |
std::copy(other.m_buffer, other.m_buffer + other.m_size, m_buffer); | |
} | |
Buffer (Buffer<T> && other) | |
: m_size(other.m_size), m_buffer(other.m_buffer) | |
{ | |
other.m_size = 0; | |
other.m_buffer = nullptr; | |
} | |
~Buffer () { delete[] m_buffer; } | |
void resize (size_t size) { | |
if (size == 0) { | |
m_size = 0; | |
if (m_buffer != nullptr) | |
delete[] m_buffer; | |
} else { | |
size = pow2sz(size); | |
T * buffer = new T [size]; | |
if (m_buffer != nullptr) { | |
if (size >= m_size) { | |
std::copy(m_buffer, m_buffer + m_size, buffer); | |
} else { | |
std::copy(m_buffer, m_buffer + size, buffer); | |
} | |
delete [] m_buffer; | |
} else { | |
std::fill(buffer, buffer + size, static_cast<T>(0)); | |
} | |
m_buffer = buffer; | |
m_size = size; | |
} | |
} | |
T & operator [] (size_t idx) { | |
if (idx >= m_size) | |
resize(idx); | |
return m_buffer[idx]; | |
} | |
protected: | |
size_t pow2sz (size_t size) { | |
size_t sz = 1; | |
while (sz < size) | |
sz *= 2; | |
return sz * 2; | |
} | |
size_t m_size; | |
T * m_buffer; | |
}; | |
template <typename T> | |
class Stack { | |
public: | |
Stack () : m_buffer(0) {} | |
Stack (const Stack<T> & other) | |
: m_buffer(other.m_buffer), m_idx(other.m_idx) {} | |
Stack (Stack<T> && other) | |
: m_buffer(std::move(other.m_buffer)), m_idx(other.m_idx) {} | |
Stack (const std::initializer_list<T> & vals) | |
: m_buffer(vals.size()) | |
{ | |
for (const auto & val : vals) { | |
push(val); | |
} | |
} | |
~Stack () {} | |
void push (const T & val) { | |
m_buffer[++m_idx] = val; | |
} | |
T & peek () { | |
return m_buffer[m_idx]; | |
} | |
T pop () { | |
assert(m_idx != 0); | |
return m_buffer[m_idx--]; | |
} | |
T & operator [] (const size_t i) { | |
assert(m_idx - i > 0); | |
return m_buffer[m_idx - i]; | |
} | |
size_t size () const { | |
return m_idx; | |
} | |
protected: | |
Buffer<T> m_buffer; | |
size_t m_idx = 0; | |
}; | |
#endif // __STACK_HPP__ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment