00001
00002
00003 #ifndef DYNAMIC_EXTENSIONS_HPP
00004 #define DYNAMIC_EXTENSIONS_HPP
00005
00006 #include "dynamic.hpp"
00007
00008 #include <map>
00009 #include <vector>
00010 #include <typeinfo>
00011
00012 #include "heap.hpp"
00013 #include "gc.hpp"
00014 #include "pickler.hpp"
00015 #include "unpickler.hpp"
00016 #include "nonroot_var.hpp"
00017
00018
00019 namespace dynamic
00020 {
00022 class DYNAMIC_API stack_trace_entry : cg::not_assignable, cg::not_copyable
00023 {
00024 stack_trace_entry * m_previous;
00025 var m_fn;
00026 public:
00027 stack_trace_entry(const var &fn);
00028 ~stack_trace_entry();
00029 static var stack_trace();
00030 };
00031
00032
00034 class DYNAMIC_API shared_var_impl : public gc::gc_object, public var_impl
00035 {
00036 public:
00037 var clone();
00038 var_cmp_result compare2(const var & other);
00039 void copy_to(void*) const;
00040 var proxy();
00041 void mark_reachable(gc::garbage_collector &);
00042 };
00043
00044
00046 template<typename T>
00047 class inline_var_impl : public var_impl
00048 {
00049 public:
00050 void copy_to(void * p) const
00051 {
00052 cg::static_assert< sizeof(T) <= sizeof(var_variant) >();
00053 new(p) T( *static_cast<const T*>(this) );
00054 }
00055 };
00056
00057
00058 namespace internal
00059 {
00061 template<typename B> class container_base : public shared_var_impl
00062 {
00063 public:
00065 virtual B & get() =0;
00066 };
00067
00069 template<typename T, typename B=T>
00070 class container_impl : public container_base<B>, cg::not_assignable, cg::not_copyable
00071 {
00072 T m_data;
00073 public:
00074 container_impl(const T & t) : m_data(t) { }
00075 container_impl() { }
00076
00077 T & get() { return m_data; }
00078 void output(ostream & ss) { ss << typeid(T).name(); }
00079
00080 void output(wostream & ss)
00081 {
00082 for(const char * s = typeid(T).name(); *s; ++s)
00083 ss << wchar_t(*s);
00084 }
00085
00086 std::string class_name() { return "native"; }
00087 var_cmp_index comparison_index() { return cmp_native; }
00088 void mark_children(gc::garbage_collector &) { }
00089 };
00090
00091 template<typename Derived,typename DerefType> template<typename T>
00092 T & var_methods<Derived,DerefType>::as()
00093 {
00094 internal::container_base<T> * p = dynamic_cast< internal::container_base<T>* >(deref().impl().shared_var());
00095
00096 if(p)
00097 return p->get();
00098 else
00099 throw not_supported(deref(), "as");
00100 }
00101
00102 }
00103
00105 template<typename T>
00106 var create(const T & t)
00107 {
00108 return new dynamic::internal::container_impl<T>(t);
00109 }
00110
00112 template<typename T>
00113 var create()
00114 {
00115 return new dynamic::internal::container_impl<T>();
00116 }
00117
00119 template<typename B, typename T>
00120 var create_base(const T & t)
00121 {
00122 return new dynamic::internal::container_impl<T,B>(t);
00123 }
00124
00125 template<typename B, typename T>
00126 var create_base()
00127 {
00128 return new dynamic::internal::container_impl<T,B>();
00129 }
00130
00131 template<typename B, typename T>
00132 var create_ref(T & t)
00133 {
00134 return new dynamic::internal::container_impl<T&,B>(t);
00135 }
00136
00137 template<typename B, typename T>
00138 T & as_derived(const var & v)
00139 {
00140 return dynamic_cast<internal::container_impl<T,B>&>(*v.impl().shared_var()).get();
00141 }
00142 }
00143
00144 #endif