0
|
1 #ifndef __vm_value_h__
|
|
2 #define __vm_value_h__
|
|
3
|
|
4 #include <iostream>
|
|
5 #include <exception>
|
|
6
|
|
7 namespace vm {
|
|
8
|
|
9 class stack_overflow: public std::exception {
|
|
10 public:
|
|
11 const char *what() const throw()
|
|
12 {
|
|
13 return "stack overflow";
|
|
14 }
|
|
15 } ;
|
|
16
|
|
17 // 固定サイズのスタック
|
|
18 // スタックオーバーフローの場合は例外を送出
|
|
19
|
|
20 template< typename Ty, int Size >
|
|
21 class stack {
|
|
22 public:
|
|
23 stack(): size_(0)
|
|
24 {
|
|
25 }
|
|
26
|
|
27 ~stack()
|
|
28 {
|
|
29 resize(0);
|
|
30 }
|
|
31
|
|
32 void push(const Ty& value)
|
|
33 {
|
|
34 if (Size <= size_)
|
|
35 throw stack_overflow();
|
|
36 *(::new(data_[size_++]) Ty) = value;
|
|
37 }
|
|
38
|
|
39 void pop()
|
|
40 {
|
|
41 ((Ty *)data_[--size_])->~Ty();
|
|
42 }
|
|
43
|
|
44 void pop(int count)
|
|
45 {
|
|
46 resize(size_ - count);
|
|
47 }
|
|
48
|
|
49 void resize(int newsize)
|
|
50 {
|
|
51 int oldsize = size_;
|
|
52
|
|
53 if (oldsize > newsize) {
|
|
54 for (int i = newsize; i < oldsize; ++i)
|
|
55 ((Ty *)data_[i])->~Ty();
|
|
56 }
|
|
57 if (oldsize < newsize) {
|
|
58 if (Size < newsize)
|
|
59 throw stack_overflow();
|
|
60 for (int i = oldsize; i < newsize; ++i)
|
|
61 ::new(data_[i]) Ty;
|
|
62 }
|
|
63 size_ = newsize;
|
|
64 }
|
|
65
|
|
66 const Ty& top() const { return *(const Ty *)data_[size_ - 1]; }
|
|
67 Ty& top() { return *(Ty *)data_[size_ - 1]; }
|
|
68
|
|
69 bool overflow() const { return size_ >= Size; }
|
|
70 bool empty() const { return size_ == 0; }
|
|
71 int size() const { return size_; }
|
|
72
|
|
73 const Ty& operator[](int index) const { return *(const Ty *)data_[index]; }
|
|
74 Ty& operator[](int index) { return *(Ty *)data_[index]; }
|
|
75
|
|
76 protected:
|
|
77 char data_[Size][sizeof(Ty)];
|
|
78 int size_;
|
|
79 } ;
|
|
80
|
|
81 } // namespace
|
|
82
|
|
83 #endif
|