Skip to content

Instantly share code, notes, and snippets.

@Adanos020
Last active May 31, 2018 12:40
Show Gist options
  • Save Adanos020/37318e340a2b13a68505459fce2dcfd4 to your computer and use it in GitHub Desktop.
Save Adanos020/37318e340a2b13a68505459fce2dcfd4 to your computer and use it in GitHub Desktop.
#pragma once
#include <range.hpp>
#include <cstring>
#include <memory>
namespace rs
{
template <class Type>
class stack : public forward_range<Type>,
public output_range<Type>
{
private: // Fields.
Type* begin;
Type* end;
public: // Methods.
stack()
: begin(nullptr)
, end(begin)
{
}
stack(stack<Type>& other)
: begin(static_cast<Type*>(malloc(other.end - other.begin)))
, end(begin + (other.end - other.begin))
{
memcpy(begin, other.begin, other.end - other.begin);
}
stack(stack<Type>&& other)
: begin(other.begin)
, end(other.end)
{
other.begin = nullptr;
other.end = nullptr;
}
~stack()
{
if (!empty()) free(begin);
}
size_t size() const
{
return end - begin;
}
void push(Type&& value)
{
put(value);
}
void push(Type& value)
{
put(value);
}
template <class... Args>
void emplace(Args&... args)
{
put(Type(args...));
}
void pop()
{
pop_front();
}
Type& top() const
{
return front();
}
public: // Overridden methods.
virtual bool empty() const override
{
return begin >= end;
}
virtual forward_range<Type>* save() override
{
return new stack<Type>(*this);
}
virtual void pop_front() override
{
assert(!empty());
begin = (Type*) realloc(begin, sizeof(Type) * (size() - 1));
if (begin) --end;
else begin = end;
}
virtual Type& front() const override
{
assert(!empty());
return *(end - 1);
}
virtual void put(Type& value) override
{
if (empty())
{
begin = (Type*) malloc(sizeof value);
*begin = value;
end = begin + 1;
}
else
{
begin = (Type*) realloc(begin, sizeof value * (size() + 1));
memcpy(end++, &value, sizeof value);
}
}
virtual void put(Type&& value) override
{
put(value); // This is now passing an lvalue reference so the method above is called.
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment