Mercurial > hg > Members > nobuyasu > SampleSource
diff Bison-Flex/BasicCompiler-StackBase/vm_value.h @ 0:db40c85cad7a default tip
upload sample source
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 May 2011 03:11:59 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Bison-Flex/BasicCompiler-StackBase/vm_value.h Mon May 09 03:11:59 2011 +0900 @@ -0,0 +1,83 @@ +#ifndef __vm_value_h__ +#define __vm_value_h__ + +#include <iostream> +#include <exception> + +namespace vm { + + class stack_overflow: public std::exception { + public: + const char *what() const throw() + { + return "stack overflow"; + } + } ; + + // 固定サイズのスタック + // スタックオーバーフローの場合は例外を送出 + + template< typename Ty, int Size > + class stack { + public: + stack(): size_(0) + { + } + + ~stack() + { + resize(0); + } + + void push(const Ty& value) + { + if (Size <= size_) + throw stack_overflow(); + *(::new(data_[size_++]) Ty) = value; + } + + void pop() + { + ((Ty *)data_[--size_])->~Ty(); + } + + void pop(int count) + { + resize(size_ - count); + } + + void resize(int newsize) + { + int oldsize = size_; + + if (oldsize > newsize) { + for (int i = newsize; i < oldsize; ++i) + ((Ty *)data_[i])->~Ty(); + } + if (oldsize < newsize) { + if (Size < newsize) + throw stack_overflow(); + for (int i = oldsize; i < newsize; ++i) + ::new(data_[i]) Ty; + } + size_ = newsize; + } + + const Ty& top() const { return *(const Ty *)data_[size_ - 1]; } + Ty& top() { return *(Ty *)data_[size_ - 1]; } + + bool overflow() const { return size_ >= Size; } + bool empty() const { return size_ == 0; } + int size() const { return size_; } + + const Ty& operator[](int index) const { return *(const Ty *)data_[index]; } + Ty& operator[](int index) { return *(Ty *)data_[index]; } + + protected: + char data_[Size][sizeof(Ty)]; + int size_; + } ; + +} // namespace + +#endif