Mercurial > hg > Members > nobuyasu > SampleSource
view boost-spirit/Compiler-boost-spirit/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 source
#ifndef __vm_value_h__ #define __vm_value_h__ #include <iostream> #include <exception> #include <string> namespace vm { // 参照カウンタ付きstring class string { public: string(): ref_(0) { } string(const std::string &str): ref_(1), str_(str) { } void addref() { ref_++; } void release() { if (--ref_ == 0) delete this; } public: int ref_; std::string str_; } ; // 変数 class value { enum { type_integer, type_string, } ; public: value() { s_ = 0; type_ = type_integer; } value(int ival) { i_ = ival; type_ = type_integer; } value(const std::string &str) { s_ = new string(str); type_ = type_string; } value(string *p) { s_ = p; type_ = type_string; } ~value() { clear(); } value(const value &a) { copy(a); } value& operator=(const value &a) { if (this == &a) return *this; clear(); copy(a); return *this; } void clear() { if (type_ == type_string) s_->release(); } void copy(const value &a) { type_ = a.type_; s_ = a.s_; if (type_ == type_string) s_->addref(); } public: union { string *s_; int i_; } ; char type_; } ; 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