comparison WindowsOnly/WinScript2/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
comparison
equal deleted inserted replaced
-1:000000000000 0:db40c85cad7a
1 #ifndef __vm_value_h__
2 #define __vm_value_h__
3
4 #include <iostream>
5 #include <exception>
6 #include <string>
7
8 namespace vm {
9
10 // 参照カウンタ付きstring
11 class string {
12 public:
13 string(): ref_(0)
14 {
15 }
16 string(const std::string &str): ref_(1), str_(str)
17 {
18 }
19
20 void addref()
21 {
22 ref_++;
23 }
24
25 void release()
26 {
27 if (--ref_ == 0)
28 delete this;
29 }
30
31 public:
32 int ref_;
33 std::string str_;
34 } ;
35
36 // 変数
37 class value {
38 enum {
39 type_integer,
40 type_string,
41 } ;
42
43 public:
44 value()
45 {
46 s_ = 0;
47 type_ = type_integer;
48 }
49
50 value(int ival)
51 {
52 i_ = ival;
53 type_ = type_integer;
54 }
55
56 value(const std::string &str)
57 {
58 s_ = new string(str);
59 type_ = type_string;
60 }
61
62 value(string *p)
63 {
64 s_ = p;
65 type_ = type_string;
66 }
67
68 ~value()
69 {
70 clear();
71 }
72
73 value(const value &a)
74 {
75 copy(a);
76 }
77
78 value& operator=(const value &a)
79 {
80 if (this == &a)
81 return *this;
82
83 clear();
84 copy(a);
85
86 return *this;
87 }
88
89 void clear()
90 {
91 if (type_ == type_string)
92 s_->release();
93 }
94
95 void copy(const value &a)
96 {
97 type_ = a.type_;
98 s_ = a.s_;
99 if (type_ == type_string)
100 s_->addref();
101 }
102
103 public:
104 union {
105 string *s_;
106 int i_;
107 } ;
108 char type_;
109 } ;
110
111 class stack_overflow: public std::exception {
112 public:
113 const char *what() const throw()
114 {
115 return "stack overflow";
116 }
117 } ;
118
119 // 固定サイズのスタック
120 // スタックオーバーフローの場合は例外を送出
121
122 template< typename Ty, int Size >
123 class stack {
124 public:
125 stack(): size_(0)
126 {
127 }
128
129 ~stack()
130 {
131 resize(0);
132 }
133
134 void push(const Ty& value)
135 {
136 if (Size <= size_)
137 throw stack_overflow();
138 *(::new(data_[size_++]) Ty) = value;
139 }
140
141 void pop()
142 {
143 ((Ty *)data_[--size_])->~Ty();
144 }
145
146 void pop(int count)
147 {
148 resize(size_ - count);
149 }
150
151 void resize(int newsize)
152 {
153 int oldsize = size_;
154
155 if (oldsize > newsize) {
156 for (int i = newsize; i < oldsize; ++i)
157 ((Ty *)data_[i])->~Ty();
158 }
159 if (oldsize < newsize) {
160 if (Size < newsize)
161 throw stack_overflow();
162 for (int i = oldsize; i < newsize; ++i)
163 ::new(data_[i]) Ty;
164 }
165 size_ = newsize;
166 }
167
168 const Ty& top() const { return *(const Ty *)data_[size_ - 1]; }
169 Ty& top() { return *(Ty *)data_[size_ - 1]; }
170
171 bool overflow() const { return size_ >= Size; }
172 bool empty() const { return size_ == 0; }
173 int size() const { return size_; }
174
175 const Ty& operator[](int index) const { return *(const Ty *)data_[index]; }
176 Ty& operator[](int index) { return *(Ty *)data_[index]; }
177
178 protected:
179 char data_[Size][sizeof(Ty)];
180 int size_;
181 } ;
182
183 } // namespace
184
185 #endif