@@ -57,24 +57,23 @@ const size_t constructor = 0;
5757class any {
5858
5959 public:
60− enum Type {
61− Thunk = 0x00,
62− Integer = 0x01,
63− Double = 0x02,
64− Character = 0x03,
65− Boolean = 0x04,
66− StringLiteral = 0x05,
67− Function = 0x06,
68− EffFunction = 0x07,
69− RawPointer = 0x08,
70− Shared = 0x10,
71− String = 0x10,
72− Map = 0x11,
73− Data = 0x12,
74− Array = 0x13,
75− Closure = 0x14,
76− EffClosure = 0x15,
77− Pointer = 0x16
60+ enum class Type {
61+ Thunk = 0x10,
62+ Integer,
63+ Double,
64+ Character,
65+ Boolean,
66+ StringLiteral,
67+ Function,
68+ EffFunction,
69+ RawPointer,
70+ String,
71+ Map,
72+ Data,
73+ Array,
74+ Closure,
75+ EffClosure,
76+ Pointer
7877 };
7978
8079 private:
@@ -151,7 +150,7 @@ class any {
151150 mutable shared<data> v;
152151 mutable shared<array> a;
153152 mutable shared<closure> l;
154− mutable shared<eff_closure> el;
153+ mutable shared<eff_closure> k;
155154 mutable shared<void> p;
156155 };
157156
@@ -202,7 +201,7 @@ class any {
202201 typename = typename std::enable_if<!std::is_same<any,T>::value &&
203202 !std::is_convertible<T,eff_fn>::value>::type>
204203 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
205− : type(Type::EffClosure), el(make_shared<_eff_closure<T>>(val)) {}
204+ : type(Type::EffClosure), k(make_shared<_eff_closure<T>>(val)) {}
206205
207206 template <typename T>
208207 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept
@@ -227,48 +226,79 @@ class any {
227226
228227#if !defined(USE_GC)
229228 private:
230− auto copy(const any& other) const noexcept -> void {
231− if (type & Type::Shared) {
232− new (&p) shared<void>(other.p);
233− } else {
234− f = other.f;
235− }
229+ template <typename T,
230+ typename U,
231+ typename = typename std::enable_if<!std::is_reference<T>::value>::type>
232+ static constexpr auto move_if_rvalue(U&& u) noexcept -> U&& {
233+ return static_cast<U&&>(u);
234+ }
235+
236+ template <typename T,
237+ typename U,
238+ typename = typename std::enable_if<std::is_reference<T>::value>::type>
239+ static constexpr auto move_if_rvalue(U& u) noexcept -> U& {
240+ return static_cast<U&>(u);
236241 }
237242
238− auto move(any&& other) const noexcept -> void {
239− if (type & Type::Shared) {
240− new (&p) shared<void>(std::move(other.p));
241− } else {
242− f = other.f;
243+ template <typename T>
244+ auto assign(T&& other) const noexcept -> void {
245+ switch (other.type) {
246+ case Type::Thunk: t = other.t; break;
247+ case Type::Integer: i = other.i; break;
248+ case Type::Double: d = other.d; break;
249+ case Type::Character: c = other.c; break;
250+ case Type::Boolean: b = other.b; break;
251+ case Type::StringLiteral: r = other.r; break;
252+ case Type::Function: f = other.f; break;
253+ case Type::EffFunction: e = other.e; break;
254+ case Type::RawPointer: u = other.u; break;
255+
256+ case Type::String: new (&s) shared<std::string>(move_if_rvalue<T>(other.s)); break;
257+ case Type::Map: new (&m) shared<map>(move_if_rvalue<T>(other.m)); break;
258+ case Type::Data: new (&v) shared<data>(move_if_rvalue<T>(other.v)); break;
259+ case Type::Array: new (&a) shared<array>(move_if_rvalue<T>(other.a)); break;
260+ case Type::Closure: new (&l) shared<closure>(move_if_rvalue<T>(other.l)); break;
261+ case Type::EffClosure: new (&k) shared<eff_closure>(move_if_rvalue<T>(other.k)); break;
262+ case Type::Pointer: new (&p) shared<void>(move_if_rvalue<T>(other.p)); break;
263+
264+ default: assert(false && "Bad 'any' type"); break;
243265 }
244266 }
245267
246268 auto destruct() -> void {
247− if (type & Type::Shared) {
248− p.~shared<void>();
269+ switch (type) {
270+ case Type::String: s.~shared<std::string>(); break;
271+ case Type::Map: m.~shared<map>(); break;
272+ case Type::Data: v.~shared<data>(); break;
273+ case Type::Array: a.~shared<array>(); break;
274+ case Type::Closure: l.~shared<closure>(); break;
275+ case Type::EffClosure: k.~shared<eff_closure>(); break;
276+ case Type::Pointer: p.~shared<void>(); break;
277+
278+ default: break;
249279 }
250280 }
251281
252282 public:
253283 any(const any& other) noexcept : type(other.type) {
254− copy(other);
284+ assign(other);
255285 }
256286
257287 any(any&& other) noexcept : type(other.type) {
258− move(std::move(other));
288+ assign(std::move(other));
259289 }
260290
261291 auto operator=(const any& rhs) noexcept -> any& {
262292 destruct();
263293 type = rhs.type;
264− copy(rhs);
294+ assign(rhs);
265295 return *this;
266296 }
267297
268298 auto operator=(any&& rhs) noexcept -> any& {
269299 destruct();
270300 type = rhs.type;
271− move(std::move(rhs));
301+ assign(std::move(rhs));
272302 return *this;
273303 }
274304