00001 #ifndef Exc_Ruby__ruby_reference__hpp_
00002 #define Exc_Ruby__ruby_reference__hpp_
00003
00004 #include "value_holder.hpp"
00005
00011 namespace Exc_Ruby
00012 {
00013
00014 #include <ruby.h>
00015 #undef TYPE
00016
00017
00019
00020
00021 template<typename T>
00022 struct Ruby_Delete_Strategy
00023 {
00025 static void ruby_delete(T * obj);
00026
00028 static void ruby_delete_bracket(T * obj);
00029
00031 static void ruby_delete_xfree(T * obj);
00032
00033 private:
00034 Ruby_Delete_Strategy();
00035 };
00036
00037
00040 template<typename T>
00041 struct Fast_Ruby_Data_Wrapper
00042 {
00044 typedef void (*Ruby_Data_Func)(T * obj);
00045
00047 static VALUE wrap(
00048 VALUE klass,
00049 Ruby_Data_Func mark,
00050 Ruby_Data_Func free,
00051 T * obj);
00052
00054 static T * unwrap(VALUE value);
00055
00056 private:
00057 Fast_Ruby_Data_Wrapper();
00058 };
00059
00060
00063 template<typename T>
00064 struct Exception_Safe_Ruby_Data_Wrapper
00065 {
00067 typedef void (*Ruby_Data_Func)(T * obj);
00068
00071 static VALUE wrap(
00072 VALUE klass,
00073 Ruby_Data_Func mark,
00074 Ruby_Data_Func free,
00075 T * obj);
00076
00079 static T * unwrap(VALUE value);
00080
00081 private:
00082 Exception_Safe_Ruby_Data_Wrapper();
00083 };
00084
00085
00087
00088
00089
00090 template<typename T, int Ruby_Type>
00091 struct Fast_Builtin_Wrapper
00092 {
00094 typedef void (*Ruby_Data_Func)(T * obj);
00095
00097 static VALUE wrap(
00098 VALUE klass,
00099 Ruby_Data_Func mark,
00100 Ruby_Data_Func free,
00101 T * obj);
00102
00106 static T * unwrap(VALUE value);
00107
00108 private:
00109 Fast_Builtin_Wrapper();
00110 };
00111
00112
00115
00116
00117
00118 template<typename T, int Ruby_Type>
00119 struct Exception_Safe_Builtin_Wrapper
00120 {
00122 typedef void (*Ruby_Data_Func)(T * obj);
00123
00125 static VALUE wrap(
00126 VALUE klass,
00127 Ruby_Data_Func mark,
00128 Ruby_Data_Func free,
00129 T * obj);
00130
00134 static T * unwrap(VALUE value);
00135
00136 private:
00137 Exception_Safe_Builtin_Wrapper();
00138 };
00139
00140 template<typename T> class Ruby_Type;
00141
00142
00144
00148
00149
00150
00151 template<
00152 typename T,
00153 class Data_Wrapper = Exception_Safe_Ruby_Data_Wrapper<T> >
00154 struct Ruby_Reference
00155 {
00156 public:
00158 typedef void (*Ruby_Data_Func)(T * obj);
00159
00163
00164
00165
00166 Ruby_Reference(
00167 T * obj,
00168 VALUE klass,
00169 Ruby_Data_Func mark_func = 0,
00170 Ruby_Data_Func free_func = Ruby_Delete_Strategy<T>::ruby_delete);
00171
00176 template<typename U>
00177 Ruby_Reference(Value_Holder value, Ruby_Type<U> const & klass, bool include_super=false);
00178
00181 Ruby_Reference(Value_Holder value, VALUE klass, bool include_super=false);
00182
00187 Ruby_Reference(Value_Holder value);
00188
00190 Ruby_Reference(Ruby_Reference const & other);
00191
00192 virtual ~Ruby_Reference();
00193
00194 T & operator*() const { return *obj_; }
00195 T * operator->() const { return obj_; }
00196 T * get() const { return obj_; }
00197 VALUE value() const { return value_; }
00198
00199 private:
00200 static void check_cpp_type(Ruby_Type<T> const & klass);
00201
00202 protected:
00203 T * obj_;
00204
00207 volatile VALUE value_;
00208 };
00209
00210
00217 #define REGISTER_WITH_RUBY_GC(type, ptr) \
00218 Ruby_Reference<type, Fast_Ruby_Data_Wrapper<type> > ( \
00219 ptr, rb_cObject).get()
00220
00221
00229 #define REGISTER_WITH_RUBY_GC_AS_GLOBAL(type, ptr, v) \
00230 *v = Ruby_Reference<type, Fast_Ruby_Data_Wrapper<type> > ( \
00231 ptr, rb_cObject).value(); \
00232 rb_global_variable(v);
00233
00234 }
00235
00236 #include "ruby_reference.ipp"
00237
00238 #endif // Exc_Ruby__ruby_reference__hpp_
00239