Mercurial > hg > Members > nobuyasu > SampleSource
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 |