@@ -65,24 +65,23 @@ any::operator char32_t() const {
6565}
6666
6767any::operator char() const {
68− const auto val = cast<decltype(c)>(*this);
68+ const auto val = static_cast<decltype(c)>(*this);
6969 assert(val <= std::numeric_limits<char>::max());
7070 return static_cast<char>(val);
7171}
7272
7373any::operator size_t() const {
74− const auto sz = cast<int>(*this);
75− assert(sz >= 0);
76− return static_cast<size_t>(sz);
74+ const auto val = static_cast<decltype(i)>(*this);
75+ assert(val >= 0);
76+ return static_cast<size_t>(val);
77+}
78+
79+any::operator const string&() const {
80+ RETURN_VALUE(Tag::String, s, *)
7781}
7882
7983any::operator const char *() const {
80− const any& variant = unthunkVariant(*this);
81− if (variant.tag == Tag::StringLiteral) {
82− return variant.r;
83− }
84− assert(variant.tag == Tag::String);
85− return variant.s->c_str();
84+ RETURN_VALUE(Tag::String, s->c_str(),)
8685}
8786
8887any::operator const array&() const {
@@ -102,16 +101,16 @@ auto any::unthunkVariant(const any& a) -> const any& {
102101}
103102
104103auto any::operator[](const size_t rhs) const -> const any& {
105− const auto& xs = cast<array>(*this);
104+ const auto& xs = static_cast<const array&>(*this);
106105 return xs[rhs];
107106}
108107
109108auto any::size() const -> size_t {
110− return cast<array>(*this).size();
109+ return static_cast<const array&>(*this).size();
111110}
112111
113112auto any::empty() const -> bool {
114− return cast<array>(*this).empty();
113+ return static_cast<const array&>(*this).empty();
115114}
116115
117116auto any::contains(const Private::Symbol key) const -> bool {
@@ -130,50 +129,17 @@ auto any::contains(const Private::Symbol key) const -> bool {
130129// Operator helper macros
131130//-----------------------------------------------------------------------------
132131
133−#define DEFINE_CSTR_EQUALS_OPERATOR() \
134− auto operator==(const any& lhs_, const char * rhs) -> bool { \
135− const any& lhs = any::unthunkVariant(lhs_); \
136− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String); \
137− if (lhs.tag == any::Tag::StringLiteral) { \
138− return (lhs.r == rhs) || (strcmp(lhs.r, rhs) == 0); \
139− } \
140− return strcmp(lhs.s->c_str(), rhs) == 0; \
141− } \
142− auto operator==(const char * lhs, const any& rhs_) -> bool { \
143− const any& rhs = any::unthunkVariant(rhs_); \
144− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String); \
145− if (rhs.tag == any::Tag::StringLiteral) { \
146− return (lhs == rhs.r) || (strcmp(lhs, rhs) == 0); \
147− } \
148− return strcmp(lhs, rhs.s->c_str()) == 0; \
149− }
150−
151−#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
152− auto operator op (const any& lhs, const char * rhs) -> bool { \
153− return strcmp(cast<const char *>(lhs), rhs) op 0; \
154− } \
155− auto operator op (const char * lhs, const any& rhs) -> bool { \
156− return strcmp(lhs, cast<const char *>(rhs)) op 0; \
157− }
158−
159132#define DEFINE_COMPARISON_OPERATOR(op) \
160− auto operator op (const any& lhs_, const any& rhs_) -> bool { \
133+ auto operator op (const any& lhs_, const any& rhs) -> bool { \
161134 const any& lhs = any::unthunkVariant(lhs_); \
162− const any& rhs = any::unthunkVariant(rhs_); \
163135 switch (lhs.tag) { \
164− case any::Tag::Integer: assert(lhs.tag == any::Tag::Integer); return lhs.i op rhs.i; \
165− case any::Tag::Double: assert(lhs.tag == any::Tag::Double); return lhs.d op rhs.d; \
166− case any::Tag::Character: assert(lhs.tag == any::Tag::Character); return lhs.c op rhs.c; \
167− case any::Tag::Boolean: assert(lhs.tag == any::Tag::Boolean); return lhs.b op rhs.b; \
168− case any::Tag::StringLiteral: \
169− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String); \
170− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String); \
171− return strcmp(lhs.r, rhs.tag == any::Tag::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
172− case any::Tag::String: \
173− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String); \
174− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String); \
175− return strcmp(lhs.s->c_str(), rhs.tag == any::Tag::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
176− case any::Tag::Pointer: return lhs.p op rhs.p; \
136+ case any::Tag::Integer: return lhs.i op static_cast<decltype(any::i)>(rhs); \
137+ case any::Tag::Double: return lhs.d op static_cast<decltype(any::d)>(rhs); \
138+ case any::Tag::Character: return lhs.c op static_cast<decltype(any::c)>(rhs); \
139+ case any::Tag::Boolean: return lhs.b op static_cast<decltype(any::b)>(rhs); \
140+ case any::Tag::String: return *lhs.s op static_cast<const string&>(rhs); \
141+ case any::Tag::RawPointer: return lhs.v op cast<decltype(any::v)>(rhs); \
142+ case any::Tag::Pointer: return lhs.p op any::unthunkVariant(rhs).p; \
177143 default: assert(false && "Unsupported tag for operator " #op); \
178144 } \
179145 return false; \
@@ -190,91 +156,56 @@ DEFINE_COMPARISON_OPERATOR(<=)
190156DEFINE_COMPARISON_OPERATOR(>)
191157DEFINE_COMPARISON_OPERATOR(>=)
192158
193−DEFINE_CSTR_EQUALS_OPERATOR()
194−DEFINE_CSTR_COMPARISON_OPERATOR(!=)
195−DEFINE_CSTR_COMPARISON_OPERATOR(<)
196−DEFINE_CSTR_COMPARISON_OPERATOR(<=)
197−DEFINE_CSTR_COMPARISON_OPERATOR(>)
198−DEFINE_CSTR_COMPARISON_OPERATOR(>=)
199−
200−auto operator+(const any& lhs_, const any& rhs_) -> any {
159+auto operator+(const any& lhs_, const any& rhs) -> any {
201160 const any& lhs = any::unthunkVariant(lhs_);
202− const any& rhs = any::unthunkVariant(rhs_);
203161 switch (lhs.tag) {
204− case any::Tag::Integer: assert(lhs.tag == any::Tag::Integer); return lhs.i + rhs.i;
205− case any::Tag::Double: assert(lhs.tag == any::Tag::Double); return lhs.d + rhs.d;
206− case any::Tag::Character: assert(lhs.tag == any::Tag::Character); return decltype(any::c){lhs.c + rhs.c};
207− case any::Tag::StringLiteral:
208− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
209− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
210− return rhs.tag == any::Tag::StringLiteral ? string(lhs.r) + rhs.r : lhs.r + *rhs.s;
211− case any::Tag::String:
212− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
213− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
214− return rhs.tag == any::Tag::StringLiteral ? *lhs.s + rhs.r : *lhs.s + *rhs.s;
162+ case any::Tag::Integer: return lhs.i + static_cast<decltype(any::i)>(rhs);
163+ case any::Tag::Double: return lhs.d + static_cast<decltype(any::d)>(rhs);
164+ case any::Tag::Character: return decltype(any::c){lhs.c + static_cast<decltype(any::c)>(rhs)};
165+ case any::Tag::String: return *lhs.s + static_cast<const string&>(rhs);
215166 default: assert(false && "Unsupported tag for '+' operator");
216167 }
217168 return nullptr;
218169}
219170
220−auto operator+(const any& lhs_, const char * rhs) -> string {
171+auto operator-(const any& lhs_, const any& rhs) -> any {
221172 const any& lhs = any::unthunkVariant(lhs_);
222− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
223− return lhs.tag == any::Tag::StringLiteral ? string(lhs.r) + rhs : *lhs.s + rhs;
224−}
225−
226−auto operator+(const char * lhs, const any& rhs_) -> string {
227− const any& rhs = any::unthunkVariant(rhs_);
228− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
229− return rhs.tag == any::Tag::StringLiteral ? lhs + string(rhs.r) : lhs + *rhs.s;
230−}
231−
232−auto operator-(const any& lhs_, const any& rhs_) -> any {
233− const any& lhs = any::unthunkVariant(lhs_);
234− const any& rhs = any::unthunkVariant(rhs_);
235− assert(lhs.tag == rhs.tag);
236173 switch (lhs.tag) {
237− case any::Tag::Integer: return lhs.i - rhs.i;
238− case any::Tag::Double: return lhs.d - rhs.d;
239− case any::Tag::Character: return decltype(any::c){lhs.c - rhs.c};
174+ case any::Tag::Integer: return lhs.i - static_cast<decltype(any::i)>(rhs);
175+ case any::Tag::Double: return lhs.d - static_cast<decltype(any::d)>(rhs);
176+ case any::Tag::Character: return decltype(any::c){lhs.c - static_cast<decltype(any::c)>(rhs)};
240177 default: assert(false && "Unsupported tag for '-' operator");
241178 }
242179 return nullptr;
243180}
244181
245−auto operator*(const any& lhs_, const any& rhs_) -> any {
182+auto operator*(const any& lhs_, const any& rhs) -> any {
246183 const any& lhs = any::unthunkVariant(lhs_);
247− const any& rhs = any::unthunkVariant(rhs_);
248− assert(lhs.tag == rhs.tag);
249184 switch (lhs.tag) {
250− case any::Tag::Integer: return lhs.i * rhs.i;
251− case any::Tag::Double: return lhs.d * rhs.d;
252− case any::Tag::Character: return decltype(lhs.c){lhs.c - rhs.c};
185+ case any::Tag::Integer: return lhs.i * static_cast<decltype(any::i)>(rhs);
186+ case any::Tag::Double: return lhs.d * static_cast<decltype(any::d)>(rhs);
187+ case any::Tag::Character: return decltype(lhs.c){lhs.c - static_cast<decltype(any::c)>(rhs)};
253188 default: assert(false && "Unsupported tag for '*' operator");
254189 }
255190 return nullptr;
256191}
257192
258−auto operator/(const any& lhs_, const any& rhs_) -> any {
193+auto operator/(const any& lhs_, const any& rhs) -> any {
259194 const any& lhs = any::unthunkVariant(lhs_);
260− const any& rhs = any::unthunkVariant(rhs_);
261− assert(lhs.tag == rhs.tag);
262195 switch (lhs.tag) {
263− case any::Tag::Integer: return lhs.i / rhs.i;
264− case any::Tag::Double: return lhs.d / rhs.d;
265− case any::Tag::Character: return decltype(any::c){lhs.c / rhs.c};
196+ case any::Tag::Integer: return lhs.i / static_cast<decltype(any::i)>(rhs);
197+ case any::Tag::Double: return lhs.d / static_cast<decltype(any::d)>(rhs);
198+ case any::Tag::Character: return decltype(any::c){lhs.c / static_cast<decltype(any::c)>(rhs)};
266199 default: assert(false && "Unsupported tag for '/' operator");
267200 }
268201 return nullptr;
269202}
270203
271−auto operator%(const any& lhs_, const any& rhs_) -> any {
204+auto operator%(const any& lhs_, const any& rhs) -> any {
272205 const any& lhs = any::unthunkVariant(lhs_);
273− const any& rhs = any::unthunkVariant(rhs_);
274− assert(lhs.tag == rhs.tag);
275206 switch (lhs.tag) {
276− case any::Tag::Integer: return lhs.i % rhs.i;
277− case any::Tag::Character: return decltype(any::c){lhs.c % rhs.c};
207+ case any::Tag::Integer: return lhs.i % static_cast<decltype(any::i)>(rhs);
208+ case any::Tag::Character: return decltype(any::c){lhs.c % static_cast<decltype(any::c)>(rhs)};
278209 default: assert(false && "Unsupported tag for '%' operator");
279210 }
280211 return nullptr;