Last active
May 31, 2018 12:40
-
-
Save Adanos020/37318e340a2b13a68505459fce2dcfd4 to your computer and use it in GitHub Desktop.
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
#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