git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: move operators out of classes; cleanup
commit53ecca27060b51b9c3a9dc9ec2d6db88785edb8e authorAndy Arvanitis <andyarvanitis@gmail.com> dateSat 16 Jan 2016, 17:50 (11 years ago) parent0711464
2 files changed+302−520
pcc/include/purescript.cc+247−387 pcc/include/purescript.hh+55−133
pcc/include/purescript.cc+247−387
@@ -16,7 +16,7 @@
1616
1717namespace PureScript {
1818
19−#define copy_data(src) \
19+#define COPY_DATA(src) \
2020 type = src.type; \
2121 switch (type) { \
2222 case Type::Integer: i = src.i; break; \
@@ -35,7 +35,7 @@ namespace PureScript {
3535 default: assert(false && "Unsupported type in copy"); \
3636 }
3737
38−#define move_data(src) \
38+#define MOVE_DATA(src) \
3939 type = src.type; \
4040 switch (type) { \
4141 case Type::Integer: i = src.i; break; \
@@ -55,26 +55,26 @@ namespace PureScript {
5555 }
5656
5757any::any(const any& other) {
58− copy_data(other);
58+ COPY_DATA(other);
5959}
6060
6161any::any(any&& other) noexcept {
62− move_data(other);
62+ MOVE_DATA(other);
6363}
6464
6565auto any::operator=(const any& rhs) -> any& {
66− copy_data(rhs);
66+ COPY_DATA(rhs);
6767 return *this;
6868}
6969
7070// Takes ownership -- might need to reconsider this
7171auto any::operator=(any& rhs) noexcept -> any& {
72− move_data(rhs);
72+ MOVE_DATA(rhs);
7373 return *this;
7474}
7575
7676auto any::operator=(any&& rhs) noexcept -> any& {
77− move_data(rhs);
77+ MOVE_DATA(rhs);
7878 return *this;
7979}
8080
@@ -98,467 +98,327 @@ any::~any() {
9898 }
9999};
100100
101− #define RETURN_VALUE(TYPE, VAL, FN) \
102− if (type == TYPE) { \
103− return FN(VAL); \
101+#define RETURN_VALUE(TYPE, VAL, FN) \
102+ if (type == TYPE) { \
103+ return FN(VAL); \
104+ } \
105+ const any* valuePtr = this; \
106+ do { \
107+ assert(valuePtr->type == Type::Thunk); \
108+ const any& value = (*valuePtr->t)(unthunk); \
109+ if (value.type == TYPE) { \
110+ return FN(value.VAL); \
104111 } \
105− const any* valuePtr = this; \
106− do { \
107− assert(valuePtr->type == Type::Thunk); \
108− const any& value = (*valuePtr->t)(unthunk); \
109− if (value.type == TYPE) { \
110− return FN(value.VAL); \
111− } \
112− valuePtr = &value; \
113− } while (valuePtr->type != Type::Unknown); \
114− assert(false && "Unknown value type"); \
115− return FN(VAL);
116−
117− template <typename T>
118− auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
119− RETURN_VALUE(Type::Integer, i,)
120− }
121− template auto any::cast<long>() const -> long;
112+ valuePtr = &value; \
113+ } while (valuePtr->type != Type::Unknown); \
114+ assert(false && "Unknown value type"); \
115+ return FN(VAL);
116+
117+template <typename T>
118+auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
119+ RETURN_VALUE(Type::Integer, i,)
120+}
121+template auto any::cast<long>() const -> long;
122122
123− template <typename T>
124− auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
125− RETURN_VALUE(Type::Double, d,)
126− }
127− template auto any::cast<double>() const -> double;
123+template <typename T>
124+auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
125+ RETURN_VALUE(Type::Double, d,)
126+}
127+template auto any::cast<double>() const -> double;
128128
129− template <typename T>
130− auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
131− RETURN_VALUE(Type::Character, c,)
132− }
133− template auto any::cast<char>() const -> char;
129+template <typename T>
130+auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
131+ RETURN_VALUE(Type::Character, c,)
132+}
133+template auto any::cast<char>() const -> char;
134134
135− template <typename T>
136− auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
137− RETURN_VALUE(Type::Boolean, b,)
138− }
139− template auto any::cast<bool>() const -> bool;
135+template <typename T>
136+auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
137+ RETURN_VALUE(Type::Boolean, b,)
138+}
139+template auto any::cast<bool>() const -> bool;
140140
141− template <typename T>
142− auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
143− RETURN_VALUE(Type::String, s, *)
144− }
145− template auto any::cast<string>() const -> const string&;
141+template <typename T>
142+auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
143+ RETURN_VALUE(Type::String, s, *)
144+}
145+template auto any::cast<string>() const -> const string&;
146146
147− template <typename T>
148− auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
149− RETURN_VALUE(Type::String, s->c_str(),)
150− }
151− template auto any::cast<const char*>() const -> const char* const;
147+template <typename T>
148+auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
149+ RETURN_VALUE(Type::String, s->c_str(),)
150+}
151+template auto any::cast<const char*>() const -> const char* const;
152152
153− template <typename T>
154− auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
155− RETURN_VALUE(Type::Map, m, *)
156− }
157− template auto any::cast<any::map>() const -> const map&;
153+template <typename T>
154+auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
155+ RETURN_VALUE(Type::Map, m, *)
156+}
157+template auto any::cast<any::map>() const -> const map&;
158158
159− template <typename T>
160− auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
161− RETURN_VALUE(Type::Vector, v, *)
162− }
163− template auto any::cast<any::vector>() const -> const vector&;
159+template <typename T>
160+auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
161+ RETURN_VALUE(Type::Vector, v, *)
162+}
163+template auto any::cast<any::vector>() const -> const vector&;
164164
165− auto any::operator()(const any& arg) const -> any {
166− if (type == Type::Function) {
167− return (*f)(arg);
168− }
169− if (type == Type::Closure) {
170− return (*l)(arg);
171− }
172− const any* valuePtr = this;
173− do {
174− assert(valuePtr->type == Type::Thunk);
175− const any& value = (*valuePtr->t)(unthunk);
176− if (value.type == Type::Function) {
177− return (*value.f)(arg);
178− }
179− if (value.type == Type::Closure) {
180− return (*value.l)(arg);
181− }
182− valuePtr = &value;
183− } while (valuePtr->type != Type::Unknown);
184− assert(false && "Unknown value type");
185− return nullptr;
165+auto any::operator()(const any& arg) const -> any {
166+ if (type == Type::Function) {
167+ return (*f)(arg);
186168 }
187−
188− auto any::operator()(const as_thunk) const -> const any& {
189− assert(type == Type::Thunk);
190− return (*t)(unthunk);
169+ if (type == Type::Closure) {
170+ return (*l)(arg);
191171 }
192−
193− auto any::operator()() const -> any {
194− if (type == Type::EffFunction) {
195− return (*e)();
172+ const any* valuePtr = this;
173+ do {
174+ assert(valuePtr->type == Type::Thunk);
175+ const any& value = (*valuePtr->t)(unthunk);
176+ if (value.type == Type::Function) {
177+ return (*value.f)(arg);
196178 }
197− const any* valuePtr = this;
198− do {
199− assert(valuePtr->type == Type::Thunk);
200− const any& value = (*valuePtr->t)(unthunk);
201− if (value.type == Type::EffFunction) {
202− return (*value.e)();
203− }
204− valuePtr = &value;
205− } while (valuePtr->type != Type::Unknown);
206− assert(false && "Unknown value type");
207− return nullptr;
208− }
209−
210− any::operator long() const {
211− RETURN_VALUE(Type::Integer, i,)
212− }
213−
214− any::operator double() const {
215− RETURN_VALUE(Type::Double, d,)
216− }
217−
218− any::operator bool() const {
219− RETURN_VALUE(Type::Boolean, b,)
220− }
221−
222− any::operator const string&() const {
223− RETURN_VALUE(Type::String, s, *)
224− }
225−
226− any::operator const map&() const {
227− RETURN_VALUE(Type::Map, m, *)
228− }
229−
230− any::operator const vector&() const {
231− RETURN_VALUE(Type::Vector, v, *)
232− }
233−
234− auto any::extractPointer() const -> void* {
235− RETURN_VALUE(Type::Pointer, p.get(),)
236− }
237−
238− auto any::extract_value(const any& a) -> const any& {
239− if (a.type != Type::Thunk) {
240− return a;
179+ if (value.type == Type::Closure) {
180+ return (*value.l)(arg);
241181 }
242− const any* valuePtr = &a;
243− do {
244− const any& value = (*valuePtr->t)(unthunk);
245− if (value.type != Type::Thunk) {
246− return value;
247− }
248− valuePtr = &value;
249− } while (valuePtr->type != Type::Unknown);
250− assert(false && "Unknown value type");
251− return a;
252− }
182+ valuePtr = &value;
183+ } while (valuePtr->type != Type::Unknown);
184+ assert(false && "Unknown value type");
185+ return nullptr;
186+}
253187
254− auto any::operator[](const map_key_t& rhs) const -> const any& {
255− RETURN_VALUE(Type::Map, m->at(rhs),)
256− }
188+auto any::operator()(const as_thunk) const -> const any& {
189+ assert(type == Type::Thunk);
190+ return (*t)(unthunk);
191+}
257192
258− auto any::operator[](const vector::size_type rhs) const -> const any& {
259− RETURN_VALUE(Type::Vector, v->at(rhs),)
193+auto any::operator()() const -> any {
194+ if (type == Type::EffFunction) {
195+ return (*e)();
260196 }
197+ const any* valuePtr = this;
198+ do {
199+ assert(valuePtr->type == Type::Thunk);
200+ const any& value = (*valuePtr->t)(unthunk);
201+ if (value.type == Type::EffFunction) {
202+ return (*value.e)();
203+ }
204+ valuePtr = &value;
205+ } while (valuePtr->type != Type::Unknown);
206+ assert(false && "Unknown value type");
207+ return nullptr;
208+}
261209
262− auto any::operator[](const any& rhs) const -> const any& {
263− RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
264− }
210+any::operator long() const {
211+ RETURN_VALUE(Type::Integer, i,)
212+}
265213
266−#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
267−auto operator OP(const T lhs, const any& rhs_) -> R { \
268− const any& rhs = any::extract_value(rhs_); \
269− assert(rhs.type == any::Type::K); \
270− return lhs OP P(rhs.V); \
214+any::operator double() const {
215+ RETURN_VALUE(Type::Double, d,)
271216}
272217
273−#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
274−auto any::operator OP(const T rhs) const -> R { \
275− const any& lhs = any::extract_value(*this); \
276− assert(lhs.type == Type::K); \
277− return P(lhs.V) OP rhs; \
218+any::operator bool() const {
219+ RETURN_VALUE(Type::Boolean, b,)
278220}
279221
280−auto any::operator==(const any& rhs_) const -> bool {
281− const any& lhs = extract_value(*this);
282− const any& rhs = extract_value(rhs_);
283− assert(lhs.type == rhs.type);
284− switch (lhs.type) {
285− case Type::Integer: return lhs.i == rhs.i;
286− case Type::Double: return lhs.d == rhs.d;
287− case Type::Character: return lhs.c == rhs.c;
288− case Type::Boolean: return lhs.b == rhs.b;
289− case Type::String: return (*lhs.s) == (*rhs.s);
290− case Type::Pointer: return lhs.p == rhs.p;
291− default: assert(false && "Unsupported type for '==' operator");
292− }
293− return false;
222+any::operator const string&() const {
223+ RETURN_VALUE(Type::String, s, *)
294224}
295225
296−DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
297−DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
298−DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
299−DEFINE_OPERATOR_RHS(Boolean, bool, ==, b, bool,)
300−DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
301−DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
226+any::operator const map&() const {
227+ RETURN_VALUE(Type::Map, m, *)
228+}
302229
303−auto any::operator!=(const any& rhs_) const -> bool {
304− const any& lhs = extract_value(*this);
305− const any& rhs = extract_value(rhs_);
306− assert(lhs.type == rhs.type);
307− switch (lhs.type) {
308− case Type::Integer: return lhs.i != rhs.i;
309− case Type::Double: return lhs.d != rhs.d;
310− case Type::Character: return lhs.c != rhs.c;
311− case Type::Boolean: return lhs.b != rhs.b;
312− case Type::String: return (*lhs.s) != (*rhs.s);
313− case Type::Pointer: return lhs.p != rhs.p;
314− default: assert(false && "Unsupported type for '!=' operator");
315− }
316− return false;
230+any::operator const vector&() const {
231+ RETURN_VALUE(Type::Vector, v, *)
317232}
318233
319−DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
320−DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
321−DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
322−DEFINE_OPERATOR_RHS(Boolean, bool, !=, b, bool,)
323−DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
324−DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
234+auto any::extractPointer() const -> void* {
235+ RETURN_VALUE(Type::Pointer, p.get(),)
236+}
325237
326−auto any::operator<(const any& rhs_) const -> bool {
327− const any& lhs = extract_value(*this);
328− const any& rhs = extract_value(rhs_);
329− assert(lhs.type == rhs.type);
330− switch (lhs.type) {
331− case Type::Integer: return lhs.i < rhs.i;
332− case Type::Double: return lhs.d < rhs.d;
333− case Type::Character: return lhs.c < rhs.c;
334− case Type::Boolean: return lhs.b < rhs.b;
335− case Type::String: return (*lhs.s) < (*rhs.s);
336− default: assert(false && "Unsupported type for '<' operator");
238+auto any::extractValue(const any& a) -> const any& {
239+ if (a.type != Type::Thunk) {
240+ return a;
337241 }
338− return false;
242+ const any* valuePtr = &a;
243+ do {
244+ const any& value = (*valuePtr->t)(unthunk);
245+ if (value.type != Type::Thunk) {
246+ return value;
247+ }
248+ valuePtr = &value;
249+ } while (valuePtr->type != Type::Unknown);
250+ assert(false && "Unknown value type");
251+ return a;
339252}
340253
341−DEFINE_OPERATOR_RHS(Integer, long, <, i, bool,)
342−DEFINE_OPERATOR_RHS(Double, double, <, d, bool,)
343−DEFINE_OPERATOR_RHS(Character, char, <, c, bool,)
344−DEFINE_OPERATOR_RHS(Boolean, bool, <, b, bool,)
345−DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
346−DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
347−
348−auto any::operator<=(const any& rhs_) const -> bool {
349− const any& lhs = extract_value(*this);
350− const any& rhs = extract_value(rhs_);
351− assert(lhs.type == rhs.type);
352− switch (lhs.type) {
353− case Type::Integer: return lhs.i <= rhs.i;
354− case Type::Double: return lhs.d <= rhs.d;
355− case Type::Character: return lhs.c <= rhs.c;
356− case Type::Boolean: return lhs.b <= rhs.b;
357− case Type::String: return (*lhs.s) <= (*rhs.s);
358− default: assert(false && "Unsupported type for '<' operator");
359− }
360− return false;
254+auto any::operator[](const map_key_t& rhs) const -> const any& {
255+ RETURN_VALUE(Type::Map, m->at(rhs),)
361256}
362257
363−DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
364−DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
365−DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
366−DEFINE_OPERATOR_RHS(Boolean, bool, <=, b, bool,)
367−DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
368−DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
258+auto any::operator[](const vector::size_type rhs) const -> const any& {
259+ RETURN_VALUE(Type::Vector, v->at(rhs),)
260+}
369261
370−auto any::operator>(const any& rhs_) const -> bool {
371− const any& lhs = extract_value(*this);
372− const any& rhs = extract_value(rhs_);
373− assert(lhs.type == rhs.type);
374− switch (lhs.type) {
375− case Type::Integer: return lhs.i > rhs.i;
376− case Type::Double: return lhs.d > rhs.d;
377− case Type::Character: return lhs.c > rhs.c;
378− case Type::Boolean: return lhs.b > rhs.b;
379− case Type::String: return (*lhs.s) > (*rhs.s);
380− default: assert(false && "Unsupported type for '>' operator");
381− }
382− return false;
262+auto any::operator[](const any& rhs) const -> const any& {
263+ RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
383264}
384265
385−DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
386−DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
387−DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
388−DEFINE_OPERATOR_RHS(Boolean, bool, >, b, bool,)
389−DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
390−DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
266+//-----------------------------------------------------------------------------
267+// Operator helper macros
268+//-----------------------------------------------------------------------------
391269
392−auto any::operator>=(const any& rhs_) const -> bool {
393− const any& lhs = extract_value(*this);
394− const any& rhs = extract_value(rhs_);
395− assert(lhs.type == rhs.type);
396− switch (lhs.type) {
397− case Type::Integer: return lhs.i >= rhs.i;
398− case Type::Double: return lhs.d >= rhs.d;
399− case Type::Character: return lhs.c >= rhs.c;
400− case Type::Boolean: return lhs.b >= rhs.b;
401− case Type::String: return (*lhs.s) >= (*rhs.s);
402− default: assert(false && "Unsupported type for '>' operator");
403− }
404− return false;
270+#define DEFINE_OPERATOR(op, ty, rty) \
271+auto operator op (const any& lhs, ty rhs) -> rty { \
272+ return lhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>() op rhs; \
273+} \
274+auto operator op (ty lhs, const any& rhs) -> rty { \
275+ return lhs op rhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>(); \
405276}
406277
407−DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
408−DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
409−DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
410−DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
411−DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
412−DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
413−
414−auto any::operator+(const any& rhs_) const -> any {
415− const any& lhs = extract_value(*this);
416− const any& rhs = extract_value(rhs_);
278+#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
279+ auto operator op (const any& lhs, const char * rhs) -> bool { \
280+ return lhs.cast<string>() op rhs; \
281+ } \
282+ auto operator op (const char * lhs, const any& rhs) -> bool { \
283+ return lhs op rhs.cast<string>(); \
284+ }
285+
286+#define DEFINE_COMPARISON_OPERATOR(op) \
287+ auto operator op (const any& lhs_, const any& rhs_) -> bool { \
288+ const any& lhs = any::extractValue(lhs_); \
289+ const any& rhs = any::extractValue(rhs_); \
290+ assert(lhs.type == rhs.type); \
291+ switch (lhs.type) { \
292+ case any::Type::Integer: return lhs.i op rhs.i; \
293+ case any::Type::Double: return lhs.d op rhs.d; \
294+ case any::Type::Character: return lhs.c op rhs.c; \
295+ case any::Type::Boolean: return lhs.b op rhs.b; \
296+ case any::Type::String: return (*lhs.s) op (*rhs.s); \
297+ case any::Type::Pointer: return lhs.p op rhs.p; \
298+ default: assert(false && "Unsupported type for operator " #op); \
299+ } \
300+ return false; \
301+ } \
302+ DEFINE_OPERATOR(op, long, bool) \
303+ DEFINE_OPERATOR(op, double, bool) \
304+ DEFINE_OPERATOR(op, char, bool) \
305+ DEFINE_OPERATOR(op, bool, bool) \
306+ DEFINE_OPERATOR(op, const string&, bool) \
307+ DEFINE_CSTR_COMPARISON_OPERATOR(op)
308+
309+//-----------------------------------------------------------------------------
310+// Operator definitions
311+//-----------------------------------------------------------------------------
312+
313+DEFINE_COMPARISON_OPERATOR(==)
314+DEFINE_COMPARISON_OPERATOR(!=)
315+DEFINE_COMPARISON_OPERATOR(<)
316+DEFINE_COMPARISON_OPERATOR(<=)
317+DEFINE_COMPARISON_OPERATOR(>)
318+DEFINE_COMPARISON_OPERATOR(>=)
319+
320+auto operator+(const any& lhs_, const any& rhs_) -> any {
321+ const any& lhs = any::extractValue(lhs_);
322+ const any& rhs = any::extractValue(rhs_);
417323 assert(lhs.type == rhs.type);
418324 switch (lhs.type) {
419− case Type::Integer: return lhs.i + rhs.i;
420− case Type::Double: return lhs.d + rhs.d;
421− case Type::Character: return any(char(lhs.c + rhs.c));
422− case Type::String: return (*lhs.s) + (*rhs.s);
325+ case any::Type::Integer: return lhs.i + rhs.i;
326+ case any::Type::Double: return lhs.d + rhs.d;
327+ case any::Type::Character: return any(char(lhs.c + rhs.c));
328+ case any::Type::String: return (*lhs.s) + (*rhs.s);
423329 default: assert(false && "Unsupported type for '+' operator");
424330 }
425331 return nullptr;
426332}
427333
428−DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
429−DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
430−DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
431−DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
432−DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
334+DEFINE_OPERATOR(+, long, long)
335+DEFINE_OPERATOR(+, double, double)
336+DEFINE_OPERATOR(+, char, char)
337+DEFINE_OPERATOR(+, const string&, string)
433338
434−auto any::operator-(const any& rhs_) const -> any {
435− const any& lhs = extract_value(*this);
436− const any& rhs = extract_value(rhs_);
339+auto operator+(const any& lhs, const char * rhs) -> string {
340+ return lhs.cast<string>() + rhs;
341+}
342+
343+auto operator+(const char * lhs, const any& rhs) -> string {
344+ return lhs + rhs.cast<string>();
345+}
346+
347+auto operator-(const any& lhs_, const any& rhs_) -> any {
348+ const any& lhs = any::extractValue(lhs_);
349+ const any& rhs = any::extractValue(rhs_);
437350 assert(lhs.type == rhs.type);
438351 switch (lhs.type) {
439− case Type::Integer: return lhs.i - rhs.i;
440− case Type::Double: return lhs.d - rhs.d;
441− case Type::Character: return any(char(lhs.c - rhs.c));
442− default: assert(false && "Unsupported type for '-' binary operator");
352+ case any::Type::Integer: return lhs.i - rhs.i;
353+ case any::Type::Double: return lhs.d - rhs.d;
354+ case any::Type::Character: return any(char(lhs.c - rhs.c));
355+ default: assert(false && "Unsupported type for '-' operator");
443356 }
444357 return nullptr;
445358}
446359
447−DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
448−DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
449−DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
360+DEFINE_OPERATOR(-, long, long)
361+DEFINE_OPERATOR(-, double, double)
362+DEFINE_OPERATOR(-, char, char)
450363
451−auto any::operator*(const any& rhs_) const -> any {
452− const any& lhs = extract_value(*this);
453− const any& rhs = extract_value(rhs_);
364+auto operator*(const any& lhs_, const any& rhs_) -> any {
365+ const any& lhs = any::extractValue(lhs_);
366+ const any& rhs = any::extractValue(rhs_);
454367 assert(lhs.type == rhs.type);
455368 switch (lhs.type) {
456− case Type::Integer: return lhs.i * rhs.i;
457− case Type::Double: return lhs.d * rhs.d;
369+ case any::Type::Integer: return lhs.i * rhs.i;
370+ case any::Type::Double: return lhs.d * rhs.d;
371+ case any::Type::Character: return any(char(lhs.c * rhs.c));
458372 default: assert(false && "Unsupported type for '*' operator");
459373 }
460374 return nullptr;
461375}
462376
463−DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
464−DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
377+DEFINE_OPERATOR(*, long, long)
378+DEFINE_OPERATOR(*, double, double)
379+DEFINE_OPERATOR(*, char, char)
465380
466−auto any::operator/(const any& rhs_) const -> any {
467− const any& lhs = extract_value(*this);
468− const any& rhs = extract_value(rhs_);
381+auto operator/(const any& lhs_, const any& rhs_) -> any {
382+ const any& lhs = any::extractValue(lhs_);
383+ const any& rhs = any::extractValue(rhs_);
469384 assert(lhs.type == rhs.type);
470385 switch (lhs.type) {
471− case Type::Integer: return lhs.i / rhs.i;
472− case Type::Double: return lhs.d / rhs.d;
386+ case any::Type::Integer: return lhs.i / rhs.i;
387+ case any::Type::Double: return lhs.d / rhs.d;
388+ case any::Type::Character: return any(char(lhs.c / rhs.c));
473389 default: assert(false && "Unsupported type for '/' operator");
474390 }
475391 return nullptr;
476392}
477393
478−DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
479−DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
394+DEFINE_OPERATOR(/, long, long)
395+DEFINE_OPERATOR(/, double, double)
396+DEFINE_OPERATOR(/, char, char)
480397
481−auto any::operator%(const any& rhs_) const -> any {
482− const any& lhs = extract_value(*this);
483− const any& rhs = extract_value(rhs_);
398+auto operator%(const any& lhs_, const any& rhs_) -> any {
399+ const any& lhs = any::extractValue(lhs_);
400+ const any& rhs = any::extractValue(rhs_);
484401 assert(lhs.type == rhs.type);
485402 switch (lhs.type) {
486− case Type::Integer: return lhs.i % rhs.i;
403+ case any::Type::Integer: return lhs.i % rhs.i;
404+ case any::Type::Character: return any(char(lhs.c % rhs.c));
487405 default: assert(false && "Unsupported type for '%' operator");
488406 }
489407 return nullptr;
490408}
491409
492−DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
410+DEFINE_OPERATOR(%, long, long)
411+DEFINE_OPERATOR(%, char, char)
493412
494−auto any::operator-() const -> any {
495− const any& lhs = any::extract_value(*this);
496− switch (lhs.type) {
497− case Type::Integer: return (- lhs.i);
498− case Type::Double: return (- lhs.d);
413+// unary negate
414+auto operator-(const any& rhs_) -> any {
415+ const any& rhs = any::extractValue(rhs_);
416+ switch (rhs.type) {
417+ case any::Type::Integer: return (- rhs.i);
418+ case any::Type::Double: return (- rhs.d);
499419 default: assert(false && "Unsupported type for unary '-' operator");
500420 }
501421 return nullptr;
502422}
503423
504−DEFINE_OPERATOR_LHS(Integer, long, ==, i, bool,)
505−DEFINE_OPERATOR_LHS(Integer, long, !=, i, bool,)
506−DEFINE_OPERATOR_LHS(Integer, long, <, i, bool,)
507−DEFINE_OPERATOR_LHS(Integer, long, <=, i, bool,)
508−DEFINE_OPERATOR_LHS(Integer, long, >, i, bool,)
509−DEFINE_OPERATOR_LHS(Integer, long, >=, i, bool,)
510−
511−DEFINE_OPERATOR_LHS(Double, double, ==, d, bool,)
512−DEFINE_OPERATOR_LHS(Double, double, !=, d, bool,)
513−DEFINE_OPERATOR_LHS(Double, double, <, d, bool,)
514−DEFINE_OPERATOR_LHS(Double, double, <=, d, bool,)
515−DEFINE_OPERATOR_LHS(Double, double, >, d, bool,)
516−DEFINE_OPERATOR_LHS(Double, double, >=, d, bool,)
517−
518−DEFINE_OPERATOR_LHS(Character, char, ==, c, bool,)
519−DEFINE_OPERATOR_LHS(Character, char, !=, c, bool,)
520−DEFINE_OPERATOR_LHS(Character, char, <, c, bool,)
521−DEFINE_OPERATOR_LHS(Character, char, <=, c, bool,)
522−DEFINE_OPERATOR_LHS(Character, char, >, c, bool,)
523−DEFINE_OPERATOR_LHS(Character, char, >=, c, bool,)
524−
525−DEFINE_OPERATOR_LHS(Boolean, bool, ==, b, bool,)
526−DEFINE_OPERATOR_LHS(Boolean, bool, !=, b, bool,)
527−DEFINE_OPERATOR_LHS(Boolean, bool, <, b, bool,)
528−DEFINE_OPERATOR_LHS(Boolean, bool, <=, b, bool,)
529−DEFINE_OPERATOR_LHS(Boolean, bool, >, b, bool,)
530−DEFINE_OPERATOR_LHS(Boolean, bool, >=, b, bool,)
531−
532−DEFINE_OPERATOR_LHS(String, string&, ==, s, bool, *)
533−DEFINE_OPERATOR_LHS(String, string&, !=, s, bool, *)
534−DEFINE_OPERATOR_LHS(String, string&, <, s, bool, *)
535−DEFINE_OPERATOR_LHS(String, string&, <=, s, bool, *)
536−DEFINE_OPERATOR_LHS(String, string&, >, s, bool, *)
537−DEFINE_OPERATOR_LHS(String, string&, >=, s, bool, *)
538−
539−DEFINE_OPERATOR_LHS(String, char* const, ==, s, bool, *)
540−DEFINE_OPERATOR_LHS(String, char* const, !=, s, bool, *)
541−DEFINE_OPERATOR_LHS(String, char* const, <, s, bool, *)
542−DEFINE_OPERATOR_LHS(String, char* const, <=, s, bool, *)
543−DEFINE_OPERATOR_LHS(String, char* const, >, s, bool, *)
544−DEFINE_OPERATOR_LHS(String, char* const, >=, s, bool, *)
545−
546−DEFINE_OPERATOR_LHS(Integer, long, +, i, long,)
547−DEFINE_OPERATOR_LHS(Integer, long, -, i, long,)
548−DEFINE_OPERATOR_LHS(Integer, long, *, i, long,)
549−DEFINE_OPERATOR_LHS(Integer, long, /, i, long,)
550−DEFINE_OPERATOR_LHS(Integer, long, %, i, long,)
551−
552−DEFINE_OPERATOR_LHS(Double, double, +, d, double,)
553−DEFINE_OPERATOR_LHS(Double, double, -, d, double,)
554−DEFINE_OPERATOR_LHS(Double, double, *, d, double,)
555−DEFINE_OPERATOR_LHS(Double, double, /, d, double,)
556−
557−DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
558−DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
559−
560−DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
561−DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
562−
563−
564424} // namespace PureScript
pcc/include/purescript.hh+55−133
@@ -33,6 +33,18 @@
3333#include <stdexcept>
3434#include "map_key.hh"
3535
36+#define DECLARE_OPERATOR(op, ty, rty) \
37+ friend auto operator op (const any&, ty) -> rty; \
38+ friend auto operator op (ty, const any&) -> rty;
39+
40+#define DECLARE_COMPARISON_OPERATOR(op) \
41+ friend auto operator op (const any&, const any&) -> bool; \
42+ DECLARE_OPERATOR(op, long, bool) \
43+ DECLARE_OPERATOR(op, double, bool) \
44+ DECLARE_OPERATOR(op, char, bool) \
45+ DECLARE_OPERATOR(op, const string&, bool) \
46+ DECLARE_OPERATOR(op, const char *, bool)
47+
3648namespace PureScript {
3749
3850using string = std::string;
@@ -206,142 +218,52 @@ class any {
206218
207219 auto extractPointer() const -> void*;
208220
209− static auto extract_value(const any&) -> const any&;
210−
211− auto operator==(const any&) const -> bool;
212− auto operator==(const long) const -> bool;
213− auto operator==(const double) const -> bool;
214− auto operator==(const char) const -> bool;
215− auto operator==(const bool) const -> bool;
216− auto operator==(const string&) const -> bool;
217− auto operator==(const char * const) const -> bool;
218−
219− auto operator!=(const any&) const -> bool;
220− auto operator!=(const long) const -> bool;
221− auto operator!=(const double) const -> bool;
222− auto operator!=(const char) const -> bool;
223− auto operator!=(const bool) const -> bool;
224− auto operator!=(const string&) const -> bool;
225− auto operator!=(const char * const) const -> bool;
226−
227− auto operator<(const any&) const -> bool;
228− auto operator<(const long) const -> bool;
229− auto operator<(const double) const -> bool;
230− auto operator<(const char) const -> bool;
231− auto operator<(const bool) const -> bool;
232− auto operator<(const string&) const -> bool;
233− auto operator<(const char * const) const -> bool;
234−
235− auto operator<=(const any&) const -> bool;
236− auto operator<=(const long) const -> bool;
237− auto operator<=(const double) const -> bool;
238− auto operator<=(const char) const -> bool;
239− auto operator<=(const bool) const -> bool;
240− auto operator<=(const string&) const -> bool;
241− auto operator<=(const char * const) const -> bool;
242−
243− auto operator>(const any&) const -> bool;
244− auto operator>(const long) const -> bool;
245− auto operator>(const double) const -> bool;
246− auto operator>(const char) const -> bool;
247− auto operator>(const bool) const -> bool;
248− auto operator>(const string&) const -> bool;
249− auto operator>(const char * const) const -> bool;
250−
251− auto operator>=(const any&) const -> bool;
252− auto operator>=(const long) const -> bool;
253− auto operator>=(const double) const -> bool;
254− auto operator>=(const char) const -> bool;
255− auto operator>=(const bool) const -> bool;
256− auto operator>=(const string&) const -> bool;
257− auto operator>=(const char * const) const -> bool;
258−
259− auto operator+(const any&) const -> any;
260− auto operator+(const long) const -> long;
261− auto operator+(const double) const -> double;
262− auto operator+(const char) const -> char;
263− auto operator+(const string&) const -> string;
264− auto operator+(const char * const) const -> string;
265−
266− auto operator-(const any&) const -> any;
267− auto operator-(const long) const -> long;
268− auto operator-(const double) const -> double;
269− auto operator-(const char) const -> char;
270−
271− auto operator*(const any&) const -> any;
272− auto operator*(const long) const -> long;
273− auto operator*(const double) const -> double;
274−
275− auto operator/(const any&) const -> any;
276− auto operator/(const long) const -> long;
277− auto operator/(const double) const -> double;
278−
279− auto operator%(const any&) const -> any;
280− auto operator%(const long) const -> long;
281−
282− auto operator-() const -> any; // unary negate
283−
284− friend auto operator==(const long, const any&) -> bool;
285− friend auto operator!=(const long, const any&) -> bool;
286− friend auto operator< (const long, const any&) -> bool;
287− friend auto operator<=(const long, const any&) -> bool;
288− friend auto operator> (const long, const any&) -> bool;
289− friend auto operator>=(const long, const any&) -> bool;
290−
291− friend auto operator==(const double, const any&) -> bool;
292− friend auto operator!=(const double, const any&) -> bool;
293− friend auto operator< (const double, const any&) -> bool;
294− friend auto operator<=(const double, const any&) -> bool;
295− friend auto operator> (const double, const any&) -> bool;
296− friend auto operator>=(const double, const any&) -> bool;
297−
298− friend auto operator==(const char, const any&) -> bool;
299− friend auto operator!=(const char, const any&) -> bool;
300− friend auto operator< (const char, const any&) -> bool;
301− friend auto operator<=(const char, const any&) -> bool;
302− friend auto operator> (const char, const any&) -> bool;
303− friend auto operator>=(const char, const any&) -> bool;
304−
305− friend auto operator==(const bool, const any&) -> bool;
306− friend auto operator!=(const bool, const any&) -> bool;
307− friend auto operator< (const bool, const any&) -> bool;
308− friend auto operator<=(const bool, const any&) -> bool;
309− friend auto operator> (const bool, const any&) -> bool;
310− friend auto operator>=(const bool, const any&) -> bool;
311−
312− friend auto operator==(const string&, const any&) -> bool;
313− friend auto operator!=(const string&, const any&) -> bool;
314− friend auto operator< (const string&, const any&) -> bool;
315− friend auto operator<=(const string&, const any&) -> bool;
316− friend auto operator> (const string&, const any&) -> bool;
317− friend auto operator>=(const string&, const any&) -> bool;
318−
319− friend auto operator==(const char* const, const any&) -> bool;
320− friend auto operator!=(const char* const, const any&) -> bool;
321− friend auto operator< (const char* const, const any&) -> bool;
322− friend auto operator<=(const char* const, const any&) -> bool;
323− friend auto operator> (const char* const, const any&) -> bool;
324− friend auto operator>=(const char* const, const any&) -> bool;
325−
326− friend auto operator+(const long, const any&) -> long;
327− friend auto operator-(const long, const any&) -> long;
328− friend auto operator*(const long, const any&) -> long;
329− friend auto operator/(const long, const any&) -> long;
330− friend auto operator%(const long, const any&) -> long;
331−
332− friend auto operator+(const double, const any&) -> double;
333− friend auto operator-(const double, const any&) -> double;
334− friend auto operator*(const double, const any&) -> double;
335− friend auto operator/(const double, const any&) -> double;
336−
337− friend auto operator+(const char, const any&) -> char;
338− friend auto operator-(const char, const any&) -> char;
339−
340− friend auto operator+(const string&, const any&) -> string;
341− friend auto operator+(const char* const, const any&) -> string;
221+ static auto extractValue(const any&) -> const any&;
222+
223+ DECLARE_COMPARISON_OPERATOR(==)
224+ DECLARE_COMPARISON_OPERATOR(!=)
225+ DECLARE_COMPARISON_OPERATOR(<)
226+ DECLARE_COMPARISON_OPERATOR(<=)
227+ DECLARE_COMPARISON_OPERATOR(>)
228+ DECLARE_COMPARISON_OPERATOR(>=)
229+
230+ friend auto operator+(const any&, const any&) -> any;
231+
232+ DECLARE_OPERATOR(+, long, long)
233+ DECLARE_OPERATOR(+, double, double)
234+ DECLARE_OPERATOR(+, char, char)
235+ DECLARE_OPERATOR(+, const string&, string)
236+ DECLARE_OPERATOR(+, const char *, string)
237+
238+ friend auto operator-(const any&, const any&) -> any;
239+
240+ DECLARE_OPERATOR(-, long, long)
241+ DECLARE_OPERATOR(-, double, double)
242+ DECLARE_OPERATOR(-, char, char)
243+
244+ friend auto operator*(const any&, const any&) -> any;
342245
246+ DECLARE_OPERATOR(*, long, long)
247+ DECLARE_OPERATOR(*, double, double)
248+ DECLARE_OPERATOR(*, char, char)
249+
250+ friend auto operator/(const any&, const any&) -> any;
251+
252+ DECLARE_OPERATOR(/, long, long)
253+ DECLARE_OPERATOR(/, double, double)
254+ DECLARE_OPERATOR(/, char, char)
255+
256+ friend auto operator%(const any&, const any&) -> any;
257+
258+ DECLARE_OPERATOR(%, long, long)
259+ DECLARE_OPERATOR(%, char, char)
260+
261+ friend auto operator-(const any&) -> any; // unary negate
343262};
344263
345264} // namespace PureScript
346265
266+#undef DECLARE_OPERATOR
267+#undef DECLARE_COMPARISON_OPERATOR
268+
347269#endif // PureScript_HH