@@ -83,7 +83,8 @@ class any {
8383 };
8484
8585 private:
86− mutable Type type = Type::Unknown;
86+ mutable Type type;
87+ mutable bool is_shared;
8788
8889 public:
8990 struct as_thunk {
@@ -102,6 +103,7 @@ class any {
102103 virtual auto operator()(const any&) const -> any = 0;
103104 virtual auto operator()(const any&, const any&) const -> any = 0;
104105 virtual auto operator()(const any&, const any&, const any&) const -> any = 0;
106+ virtual ~closure() {}
105107 };
106108
107109 template <typename T>
@@ -204,83 +206,129 @@ class any {
204206
205207 public:
206208
207− any(const long val) : type(Type::Integer), i(val) {}
208− any(const int val) : type(Type::Integer), i(val) {}
209− any(const unsigned int val) : type(Type::Integer), i(val) {}
210− any(const double val) : type(Type::Double), d(val) {}
211− any(const char val) : type(Type::Character), c(val) {}
209+ any(const long val) : type(Type::Integer), is_shared(false), i(val) {}
210+ any(const int val) : type(Type::Integer), is_shared(false), i(val) {}
211+ any(const unsigned int val) : type(Type::Integer), is_shared(false), i(val) {}
212+ any(const double val) : type(Type::Double), is_shared(false), d(val) {}
213+ any(const char val) : type(Type::Character), is_shared(false), c(val) {}
212214
213215 template <typename T, typename = typename std::enable_if<std::is_same<bool,T>::value>::type>
214− any(const T val) : type(Type::Boolean), b(val) {}
216+ any(const T val) : type(Type::Boolean), is_shared(false), b(val) {}
215217
216218 template <size_t N>
217− any(const char (&val)[N]) : type(Type::StringLiteral), r(val) {}
218− any(char * val) : type(Type::String), s(make_shared<std::string>(val)) {}
219+ any(const char (&val)[N]) : type(Type::StringLiteral), is_shared(false), r(val) {}
220+ any(char * val) : type(Type::String), is_shared(true), s(make_shared<std::string>(val)) {}
219221
220− any(const std::string& val) : type(Type::String), s(make_shared<std::string>(val)) {}
221− any(std::string&& val) : type(Type::String), s(make_shared<std::string>(std::move(val))) {}
222+ any(const std::string& val) : type(Type::String), is_shared(true), s(make_shared<std::string>(val)) {}
223+ any(std::string&& val) : type(Type::String), is_shared(true), s(make_shared<std::string>(std::move(val))) {}
222224
223− any(const shared<std::string>& val) : type(Type::String), s(val) {}
224− any(shared<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
225+ any(const shared<std::string>& val) : type(Type::String), is_shared(true), s(val) {}
226+ any(shared<std::string>&& val) noexcept : type(Type::String), is_shared(true), s(std::move(val)) {}
225227
226− any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
227− any(map&& val) noexcept : type(Type::Map), m(make_shared<map>(std::move(val))) {}
228+ any(const map& val) : type(Type::Map), is_shared(true), m(make_shared<map>(val)) {}
229+ any(map&& val) noexcept : type(Type::Map), is_shared(true), m(make_shared<map>(std::move(val))) {}
228230
229− any(const data& val) : type(Type::Data), v(make_shared<data>(val)) {}
230− any(data&& val) noexcept : type(Type::Data), v(make_shared<data>(std::move(val))) {}
231+ any(const data& val) : type(Type::Data), is_shared(true), v(make_shared<data>(val)) {}
232+ any(data&& val) noexcept : type(Type::Data), is_shared(true), v(make_shared<data>(std::move(val))) {}
231233
232− any(const array& val) : type(Type::Array), a(make_shared<array>(val)) {}
233− any(array&& val) noexcept : type(Type::Array), a(make_shared<array>(std::move(val))) {}
234+ any(const array& val) : type(Type::Array), is_shared(true), a(make_shared<array>(val)) {}
235+ any(array&& val) noexcept : type(Type::Array), is_shared(true), a(make_shared<array>(std::move(val))) {}
234236
235237 template <typename T>
236238 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
237− : type(Type::Function), f(val) {}
239+ : type(Type::Function), is_shared(false), f(val) {}
238240
239241 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
240242 !std::is_convertible<T,fn>::value>::type>
241243 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
242− : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
244+ : type(Type::Closure), is_shared(true), l(make_shared<_closure<T>>(val)) {}
243245
244246 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
245247 !std::is_convertible<T,fn>::value>::type>
246248 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&,
247249 const any&)>,T>::value>::type* = 0)
248− : type(Type::Closure), l(make_shared<_closure2<T>>(val)) {}
250+ : type(Type::Closure), is_shared(true), l(make_shared<_closure2<T>>(val)) {}
249251
250252 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
251253 !std::is_convertible<T,fn>::value>::type>
252254 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&,
253255 const any&,
254256 const any&)>,T>::value>::type* = 0)
255− : type(Type::Closure), l(make_shared<_closure3<T>>(val)) {}
257+ : type(Type::Closure), is_shared(true), l(make_shared<_closure3<T>>(val)) {}
256258
257259 template <typename T>
258260 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
259− : type(Type::EffFunction), e(make_shared<_eff_fn<T>>(val)) {}
261+ : type(Type::EffFunction), is_shared(true), e(make_shared<_eff_fn<T>>(val)) {}
260262
261263 template <typename T>
262264 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0)
263− : type(Type::Thunk), t(val) {}
265+ : type(Type::Thunk), is_shared(false), t(val) {}
264266
265267 template <typename T>
266268 any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0)
267− : type(Type::Pointer), p(val) {}
269+ : type(Type::Pointer), is_shared(true), p(val) {}
268270
269271 template <typename T>
270272 any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
271− : type(Type::Pointer), p(std::move(val)) {}
273+ : type(Type::Pointer), is_shared(true), p(std::move(val)) {}
272274
273− any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
275+ any(std::nullptr_t) : type(Type::Pointer), is_shared(true), p(nullptr) {}
274276
275− any(const any&);
276− any(any&&) noexcept;
277+ private:
278+
279+ auto copy(const any& other) const -> void {
280+ if (is_shared) {
281+ new (&p) shared<void>(other.p);
282+ } else {
283+ f = other.f;
284+ }
285+ }
277286
278− auto operator=(const any&) -> any&;
279− auto operator=(any&) noexcept -> any&;
280− auto operator=(any&&) noexcept -> any&;
287+ auto move(any& other) const noexcept -> void {
288+ if (is_shared) {
289+ new (&p) shared<void>(std::move(other.p));
290+ } else {
291+ f = other.f;
292+ }
293+ }
294+
295+ auto del() noexcept -> void {
296+ if (is_shared) {
297+ p.~shared<void>();
298+ }
299+ }
300+
301+ public:
302+
303+ any(const any& other) : type(other.type), is_shared(other.is_shared) {
304+ copy(other);
305+ }
306+
307+ any(any&& other) noexcept : type(other.type), is_shared(other.is_shared) {
308+ move(other);
309+ }
310+
311+ auto operator=(const any& rhs) -> any& {
312+ del();
313+ type = rhs.type;
314+ is_shared = rhs.is_shared;
315+ copy(rhs);
316+ return *this;
317+ }
318+
319+ auto operator=(any&& rhs) noexcept -> any& {
320+ del();
321+ type = rhs.type;
322+ is_shared = rhs.is_shared;
323+ move(rhs);
324+ return *this;
325+ }
281326
282327 any() = delete;
283− ~any();
328+
329+ ~any() {
330+ del();
331+ }
284332
285333 template <typename T>
286334 auto cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type;