rice 4.0.4 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/CONTRIBUTORS.md +2 -0
- data/Rakefile +1 -1
- data/include/rice/rice.hpp +2851 -1955
- data/include/rice/stl.hpp +1654 -287
- data/lib/mkmf-rice.rb +5 -2
- data/lib/version.rb +1 -1
- data/rice/Arg.hpp +6 -6
- data/rice/Arg.ipp +8 -9
- data/rice/Constructor.hpp +2 -2
- data/rice/Data_Object.ipp +69 -15
- data/rice/Data_Object_defn.hpp +1 -15
- data/rice/Data_Type.ipp +56 -86
- data/rice/Data_Type_defn.hpp +14 -17
- data/rice/Director.hpp +0 -1
- data/rice/Enum.ipp +31 -22
- data/rice/Exception.ipp +2 -3
- data/rice/Exception_defn.hpp +5 -5
- data/rice/HandlerRegistration.hpp +15 -0
- data/rice/Return.hpp +5 -4
- data/rice/Return.ipp +8 -3
- data/rice/detail/ExceptionHandler.hpp +8 -0
- data/rice/detail/ExceptionHandler.ipp +28 -0
- data/rice/detail/{Exception_Handler_defn.hpp → ExceptionHandler_defn.hpp} +17 -21
- data/rice/detail/HandlerRegistry.hpp +51 -0
- data/rice/detail/HandlerRegistry.ipp +20 -0
- data/rice/detail/InstanceRegistry.hpp +34 -0
- data/rice/detail/InstanceRegistry.ipp +50 -0
- data/rice/detail/MethodInfo.ipp +1 -1
- data/rice/detail/NativeAttribute.hpp +26 -15
- data/rice/detail/NativeAttribute.ipp +76 -47
- data/rice/detail/NativeFunction.hpp +64 -14
- data/rice/detail/NativeFunction.ipp +138 -86
- data/rice/detail/NativeIterator.hpp +49 -0
- data/rice/detail/NativeIterator.ipp +102 -0
- data/rice/detail/NativeRegistry.hpp +31 -0
- data/rice/detail/{method_data.ipp → NativeRegistry.ipp} +20 -16
- data/rice/detail/Registries.hpp +26 -0
- data/rice/detail/Registries.ipp +23 -0
- data/rice/detail/RubyFunction.hpp +6 -11
- data/rice/detail/RubyFunction.ipp +10 -22
- data/rice/detail/Type.hpp +1 -1
- data/rice/detail/Type.ipp +2 -2
- data/rice/detail/TypeRegistry.hpp +8 -11
- data/rice/detail/TypeRegistry.ipp +3 -28
- data/rice/detail/Wrapper.hpp +0 -2
- data/rice/detail/Wrapper.ipp +74 -24
- data/rice/detail/cpp_protect.hpp +93 -0
- data/rice/detail/default_allocation_func.ipp +1 -1
- data/rice/detail/from_ruby.ipp +206 -2
- data/rice/detail/to_ruby.ipp +39 -5
- data/rice/detail/to_ruby_defn.hpp +1 -1
- data/rice/forward_declares.ipp +6 -0
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -6
- data/rice/rice.hpp +29 -24
- data/rice/stl.hpp +6 -1
- data/sample/callbacks/extconf.rb +0 -1
- data/sample/enum/extconf.rb +0 -1
- data/sample/inheritance/extconf.rb +0 -1
- data/sample/map/extconf.rb +0 -1
- data/test/embed_ruby.cpp +6 -15
- data/test/ext/t1/extconf.rb +0 -1
- data/test/ext/t2/extconf.rb +0 -1
- data/test/extconf.rb +0 -1
- data/test/test_Array.cpp +20 -24
- data/test/test_Attribute.cpp +6 -6
- data/test/test_Class.cpp +8 -47
- data/test/test_Constructor.cpp +0 -2
- data/test/test_Data_Object.cpp +25 -11
- data/test/test_Data_Type.cpp +124 -28
- data/test/test_Director.cpp +12 -13
- data/test/test_Enum.cpp +65 -26
- data/test/test_Inheritance.cpp +9 -9
- data/test/test_Iterator.cpp +134 -5
- data/test/test_Keep_Alive.cpp +7 -7
- data/test/test_Keep_Alive_No_Wrapper.cpp +80 -0
- data/test/test_Memory_Management.cpp +1 -1
- data/test/test_Module.cpp +25 -62
- data/test/test_Object.cpp +75 -3
- data/test/test_Ownership.cpp +12 -13
- data/test/test_Self.cpp +12 -13
- data/test/test_Stl_Map.cpp +696 -0
- data/test/test_Stl_Optional.cpp +3 -3
- data/test/test_Stl_Pair.cpp +38 -2
- data/test/test_Stl_Reference_Wrapper.cpp +102 -0
- data/test/test_Stl_SmartPointer.cpp +49 -9
- data/test/test_Stl_String.cpp +5 -2
- data/test/test_Stl_Unordered_Map.cpp +697 -0
- data/test/test_Stl_Variant.cpp +346 -0
- data/test/test_Stl_Vector.cpp +200 -41
- data/test/test_Struct.cpp +3 -3
- data/test/test_To_From_Ruby.cpp +8 -2
- data/test/test_Tracking.cpp +239 -0
- data/test/unittest.hpp +21 -4
- metadata +24 -13
- data/rice/detail/Exception_Handler.hpp +0 -8
- data/rice/detail/Exception_Handler.ipp +0 -28
- data/rice/detail/Iterator.hpp +0 -23
- data/rice/detail/Iterator.ipp +0 -47
- data/rice/detail/function_traits.hpp +0 -124
- data/rice/detail/method_data.hpp +0 -29
- data/rice/detail/rice_traits.hpp +0 -116
- data/rice/ruby_try_catch.hpp +0 -86
@@ -0,0 +1,49 @@
|
|
1
|
+
#ifndef Rice_NativeIterator__hpp_
|
2
|
+
#define Rice_NativeIterator__hpp_
|
3
|
+
|
4
|
+
#include "traits/function_traits.hpp"
|
5
|
+
|
6
|
+
namespace Rice::detail
|
7
|
+
{
|
8
|
+
template<typename T, typename Iterator_Func_T>
|
9
|
+
class NativeIterator
|
10
|
+
{
|
11
|
+
public:
|
12
|
+
using NativeIterator_T = NativeIterator<T, Iterator_Func_T>;
|
13
|
+
using Iterator_T = typename function_traits<Iterator_Func_T>::return_type;
|
14
|
+
using Value_T = typename std::iterator_traits<Iterator_T>::value_type;
|
15
|
+
using Difference_T = typename std::iterator_traits<Iterator_T>::difference_type;
|
16
|
+
|
17
|
+
public:
|
18
|
+
// Register function with Ruby
|
19
|
+
void static define(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end);
|
20
|
+
|
21
|
+
// Static member function that Ruby calls
|
22
|
+
static VALUE call(VALUE self);
|
23
|
+
|
24
|
+
public:
|
25
|
+
// Disallow creating/copying/moving
|
26
|
+
NativeIterator() = delete;
|
27
|
+
NativeIterator(const NativeIterator_T&) = delete;
|
28
|
+
NativeIterator(NativeIterator_T&&) = delete;
|
29
|
+
void operator=(const NativeIterator_T&) = delete;
|
30
|
+
void operator=(NativeIterator_T&&) = delete;
|
31
|
+
|
32
|
+
VALUE operator()(VALUE self);
|
33
|
+
|
34
|
+
protected:
|
35
|
+
NativeIterator(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end);
|
36
|
+
|
37
|
+
private:
|
38
|
+
VALUE createRubyEnumerator(VALUE self);
|
39
|
+
|
40
|
+
private:
|
41
|
+
VALUE klass_;
|
42
|
+
std::string method_name_;
|
43
|
+
Iterator_Func_T begin_;
|
44
|
+
Iterator_Func_T end_;
|
45
|
+
};
|
46
|
+
}
|
47
|
+
#include "NativeIterator.ipp"
|
48
|
+
|
49
|
+
#endif // Rice_NativeIterator__hpp_
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#include <iterator>
|
2
|
+
#include <functional>
|
3
|
+
#include <type_traits>
|
4
|
+
|
5
|
+
#include "cpp_protect.hpp"
|
6
|
+
#include "NativeRegistry.hpp"
|
7
|
+
|
8
|
+
namespace Rice::detail
|
9
|
+
{
|
10
|
+
template <typename T, typename Iterator_Func_T>
|
11
|
+
inline void NativeIterator<T, Iterator_Func_T>::define(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end)
|
12
|
+
{
|
13
|
+
// Tell Ruby to invoke the static method call on this class
|
14
|
+
detail::protect(rb_define_method, klass, method_name.c_str(), (RUBY_METHOD_FUNC)&NativeIterator_T::call, 0);
|
15
|
+
|
16
|
+
// Now create a NativeIterator instance and save it to the natives registry keyed on
|
17
|
+
// Ruby klass and method id. There may be multiple NativeIterator instances
|
18
|
+
// because the same C++ method could be mapped to multiple Ruby methods.
|
19
|
+
NativeIterator_T* native = new NativeIterator_T(klass, method_name, begin, end);
|
20
|
+
detail::Registries::instance.natives.add(klass, Identifier(method_name).id(), native);
|
21
|
+
}
|
22
|
+
|
23
|
+
template<typename T, typename Iterator_Func_T>
|
24
|
+
inline VALUE NativeIterator<T, Iterator_Func_T>::call(VALUE self)
|
25
|
+
{
|
26
|
+
// Look up the native function based on the Ruby klass and method id
|
27
|
+
NativeIterator_T* nativeIterator = detail::Registries::instance.natives.lookup<NativeIterator_T*>();
|
28
|
+
|
29
|
+
return cpp_protect([&]
|
30
|
+
{
|
31
|
+
return nativeIterator->operator()(self);
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
template <typename T, typename Iterator_Func_T>
|
36
|
+
inline NativeIterator<T, Iterator_Func_T>::NativeIterator(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end) :
|
37
|
+
klass_(klass), method_name_(method_name), begin_(begin), end_(end)
|
38
|
+
{
|
39
|
+
}
|
40
|
+
|
41
|
+
template<typename T, typename Iterator_Func_T>
|
42
|
+
inline VALUE NativeIterator<T, Iterator_Func_T>::createRubyEnumerator(VALUE self)
|
43
|
+
{
|
44
|
+
auto rb_size_function = [](VALUE recv, VALUE argv, VALUE eobj) -> VALUE
|
45
|
+
{
|
46
|
+
// Since we can't capture VALUE self from above (because then we can't send
|
47
|
+
// this lambda to rb_enumeratorize_with_size), extract it from recv
|
48
|
+
return cpp_protect([&]
|
49
|
+
{
|
50
|
+
// Get the iterator instance
|
51
|
+
using Iter_T = NativeIterator<T, Iterator_Func_T>;
|
52
|
+
// Class is easy
|
53
|
+
VALUE klass = protect(rb_class_of, recv);
|
54
|
+
// Read the method_id from an attribute we added to the enumerator instance
|
55
|
+
ID method_id = protect(rb_ivar_get, eobj, rb_intern("rice_method"));
|
56
|
+
Iter_T* iterator = detail::Registries::instance.natives.lookup<Iter_T*>(klass, method_id);
|
57
|
+
|
58
|
+
// Get the wrapped C++ instance
|
59
|
+
T* receiver = detail::From_Ruby<T*>().convert(recv);
|
60
|
+
|
61
|
+
// Get the distance
|
62
|
+
Iterator_T begin = std::invoke(iterator->begin_, *receiver);
|
63
|
+
Iterator_T end = std::invoke(iterator->end_, *receiver);
|
64
|
+
Difference_T distance = std::distance(begin, end);
|
65
|
+
|
66
|
+
return detail::To_Ruby<Difference_T>().convert(distance);
|
67
|
+
});
|
68
|
+
};
|
69
|
+
|
70
|
+
VALUE method_sym = Identifier(this->method_name_).to_sym();
|
71
|
+
VALUE enumerator = protect(rb_enumeratorize_with_size, self, method_sym, 0, nullptr, rb_size_function);
|
72
|
+
|
73
|
+
// Hack the enumerator object by storing name_ on the enumerator object so
|
74
|
+
// the rb_size_function above has access to it
|
75
|
+
ID method_id = Identifier(this->method_name_).id();
|
76
|
+
protect(rb_ivar_set, enumerator, rb_intern("rice_method"), method_id );
|
77
|
+
|
78
|
+
return enumerator;
|
79
|
+
}
|
80
|
+
|
81
|
+
template<typename T, typename Iterator_Func_T>
|
82
|
+
inline VALUE NativeIterator<T, Iterator_Func_T>::operator()(VALUE self)
|
83
|
+
{
|
84
|
+
if (!protect(rb_block_given_p))
|
85
|
+
{
|
86
|
+
return createRubyEnumerator(self);
|
87
|
+
}
|
88
|
+
else
|
89
|
+
{
|
90
|
+
T* receiver = detail::From_Ruby<T*>().convert(self);
|
91
|
+
Iterator_T it = std::invoke(this->begin_, *receiver);
|
92
|
+
Iterator_T end = std::invoke(this->end_, *receiver);
|
93
|
+
|
94
|
+
for (; it != end; ++it)
|
95
|
+
{
|
96
|
+
protect(rb_yield, detail::To_Ruby<Value_T>().convert(*it));
|
97
|
+
}
|
98
|
+
|
99
|
+
return self;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#ifndef Rice__detail__NativeRegistry__hpp
|
2
|
+
#define Rice__detail__NativeRegistry__hpp
|
3
|
+
|
4
|
+
#include <unordered_map>
|
5
|
+
#include <any>
|
6
|
+
|
7
|
+
#include "ruby.hpp"
|
8
|
+
|
9
|
+
namespace Rice::detail
|
10
|
+
{
|
11
|
+
class NativeRegistry
|
12
|
+
{
|
13
|
+
public:
|
14
|
+
// Add a new native callable object keyed by Ruby class and method_id
|
15
|
+
void add(VALUE klass, ID method_id, std::any callable);
|
16
|
+
|
17
|
+
// Returns the Rice data for the currently active Ruby method
|
18
|
+
template <typename Return_T>
|
19
|
+
Return_T lookup();
|
20
|
+
|
21
|
+
template <typename Return_T>
|
22
|
+
Return_T lookup(VALUE klass, ID method_id);
|
23
|
+
|
24
|
+
private:
|
25
|
+
size_t key(VALUE klass, ID method_id);
|
26
|
+
std::unordered_map<size_t, std::any> natives_ = {};
|
27
|
+
};
|
28
|
+
}
|
29
|
+
#include "NativeRegistry.ipp"
|
30
|
+
|
31
|
+
#endif // Rice__detail__NativeRegistry__hpp
|
@@ -6,11 +6,13 @@
|
|
6
6
|
// back to the C-API underneath again.
|
7
7
|
#undef rb_define_method_id
|
8
8
|
|
9
|
+
#include "RubyFunction.hpp"
|
10
|
+
|
9
11
|
namespace Rice::detail
|
10
12
|
{
|
11
13
|
// Effective Java (2nd edition)
|
12
14
|
// https://stackoverflow.com/a/2634715
|
13
|
-
inline size_t
|
15
|
+
inline size_t NativeRegistry::key(VALUE klass, ID id)
|
14
16
|
{
|
15
17
|
if (rb_type(klass) == T_ICLASS)
|
16
18
|
{
|
@@ -21,18 +23,30 @@ namespace Rice::detail
|
|
21
23
|
return (prime + klass) * prime + id;
|
22
24
|
}
|
23
25
|
|
26
|
+
inline void NativeRegistry::add(VALUE klass, ID method_id, std::any callable)
|
27
|
+
{
|
28
|
+
// Now store data about it
|
29
|
+
this->natives_[key(klass, method_id)] = callable;
|
30
|
+
}
|
31
|
+
|
24
32
|
template <typename Return_T>
|
25
|
-
inline Return_T
|
33
|
+
inline Return_T NativeRegistry::lookup()
|
26
34
|
{
|
27
|
-
ID
|
35
|
+
ID method_id;
|
28
36
|
VALUE klass;
|
29
|
-
if (!rb_frame_method_id_and_class(&
|
37
|
+
if (!rb_frame_method_id_and_class(&method_id, &klass))
|
30
38
|
{
|
31
39
|
rb_raise(rb_eRuntimeError, "Cannot get method id and class for function");
|
32
40
|
}
|
33
41
|
|
34
|
-
|
35
|
-
|
42
|
+
return this->lookup<Return_T>(klass, method_id);
|
43
|
+
}
|
44
|
+
|
45
|
+
template <typename Return_T>
|
46
|
+
inline Return_T NativeRegistry::lookup(VALUE klass, ID method_id)
|
47
|
+
{
|
48
|
+
auto iter = this->natives_.find(key(klass, method_id));
|
49
|
+
if (iter == this->natives_.end())
|
36
50
|
{
|
37
51
|
rb_raise(rb_eRuntimeError, "Could not find data for klass and method id");
|
38
52
|
}
|
@@ -40,14 +54,4 @@ namespace Rice::detail
|
|
40
54
|
std::any data = iter->second;
|
41
55
|
return std::any_cast<Return_T>(data);
|
42
56
|
}
|
43
|
-
|
44
|
-
template<typename Function_T>
|
45
|
-
inline void MethodData::define_method(VALUE klass, ID id, Function_T func, int arity, std::any data)
|
46
|
-
{
|
47
|
-
// Define the method
|
48
|
-
protect(rb_define_method_id, klass, id, (RUBY_METHOD_FUNC)func, arity);
|
49
|
-
|
50
|
-
// Now store data about it
|
51
|
-
methodWrappers_[key(klass, id)] = data;
|
52
|
-
}
|
53
57
|
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#ifndef Rice__Registries__hpp_
|
2
|
+
#define Rice__Registries__hpp_
|
3
|
+
|
4
|
+
#include "HandlerRegistry.hpp"
|
5
|
+
#include "InstanceRegistry.hpp"
|
6
|
+
#include "NativeRegistry.hpp"
|
7
|
+
#include "TypeRegistry.hpp"
|
8
|
+
|
9
|
+
namespace Rice::detail
|
10
|
+
{
|
11
|
+
class Registries
|
12
|
+
{
|
13
|
+
public:
|
14
|
+
static Registries instance;
|
15
|
+
|
16
|
+
public:
|
17
|
+
HandlerRegistry handlers;
|
18
|
+
InstanceRegistry instances;
|
19
|
+
NativeRegistry natives;
|
20
|
+
TypeRegistry types;
|
21
|
+
};
|
22
|
+
}
|
23
|
+
|
24
|
+
#include "Registries.ipp"
|
25
|
+
|
26
|
+
#endif // Rice__Registries__hpp_
|
@@ -0,0 +1,23 @@
|
|
1
|
+
namespace Rice::detail
|
2
|
+
{
|
3
|
+
//Initialize static variables here.
|
4
|
+
inline Registries Registries::instance;
|
5
|
+
|
6
|
+
// TODO - Big hack here but this code is dependent on internals
|
7
|
+
template<typename T>
|
8
|
+
bool Type<T>::verify()
|
9
|
+
{
|
10
|
+
// Use intrinsic_type so that we don't have to define specializations
|
11
|
+
// for pointers, references, const, etc.
|
12
|
+
using Intrinsic_T = intrinsic_type<T>;
|
13
|
+
|
14
|
+
if constexpr (std::is_fundamental_v<Intrinsic_T>)
|
15
|
+
{
|
16
|
+
return true;
|
17
|
+
}
|
18
|
+
else
|
19
|
+
{
|
20
|
+
return Registries::instance.types.verifyDefined<Intrinsic_T>();
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
@@ -11,9 +11,12 @@ namespace Rice::detail
|
|
11
11
|
instance of a Ruby_Function. That instance then in turn calls the original
|
12
12
|
Ruby method passing along its required arguments. */
|
13
13
|
|
14
|
-
template<typename Function_T, typename
|
14
|
+
template<typename Function_T, typename...Arg_Ts>
|
15
15
|
class RubyFunction
|
16
16
|
{
|
17
|
+
public:
|
18
|
+
using Return_T = typename function_traits<Function_T>::return_type;
|
19
|
+
|
17
20
|
public:
|
18
21
|
RubyFunction(Function_T func, const Arg_Ts&... args);
|
19
22
|
Return_T operator()();
|
@@ -23,17 +26,9 @@ namespace Rice::detail
|
|
23
26
|
std::tuple<Arg_Ts...> args_;
|
24
27
|
};
|
25
28
|
|
26
|
-
template<typename
|
27
|
-
|
28
|
-
}
|
29
|
-
|
30
|
-
namespace Rice
|
31
|
-
{
|
32
|
-
template<typename Return_T, typename ...Arg_Ts>
|
33
|
-
[[deprecated("Please use detail::protect")]]
|
34
|
-
Return_T protect(Return_T(*func)(Arg_Ts...), Arg_Ts...args);
|
29
|
+
template<typename Function_T, typename ...Arg_Ts>
|
30
|
+
auto protect(Function_T func, Arg_Ts...args);
|
35
31
|
}
|
36
|
-
|
37
32
|
#include "RubyFunction.ipp"
|
38
33
|
|
39
34
|
#endif // Rice__detail__ruby_function__hpp_
|
@@ -5,14 +5,14 @@
|
|
5
5
|
|
6
6
|
namespace Rice::detail
|
7
7
|
{
|
8
|
-
template<typename Function_T, typename
|
9
|
-
inline RubyFunction<Function_T,
|
8
|
+
template<typename Function_T, typename...Arg_Ts>
|
9
|
+
inline RubyFunction<Function_T, Arg_Ts...>::RubyFunction(Function_T func, const Arg_Ts&... args)
|
10
10
|
: func_(func), args_(std::forward_as_tuple(args...))
|
11
11
|
{
|
12
12
|
}
|
13
13
|
|
14
|
-
template<typename Function_T, typename
|
15
|
-
inline
|
14
|
+
template<typename Function_T, typename...Arg_Ts>
|
15
|
+
inline typename RubyFunction<Function_T, Arg_Ts...>::Return_T RubyFunction<Function_T, Arg_Ts...>::operator()()
|
16
16
|
{
|
17
17
|
const int TAG_RAISE = 0x6; // From Ruby header files
|
18
18
|
int state = 0;
|
@@ -27,8 +27,8 @@ namespace Rice::detail
|
|
27
27
|
thread_local std::any result;
|
28
28
|
|
29
29
|
// Callback that will invoke the Ruby function
|
30
|
-
using Functor_T = RubyFunction<Function_T,
|
31
|
-
auto callback = [](VALUE value)
|
30
|
+
using Functor_T = RubyFunction<Function_T, Arg_Ts...>;
|
31
|
+
auto callback = [](VALUE value) -> VALUE
|
32
32
|
{
|
33
33
|
Functor_T* functor = (Functor_T*)value;
|
34
34
|
|
@@ -58,7 +58,7 @@ namespace Rice::detail
|
|
58
58
|
else
|
59
59
|
{
|
60
60
|
VALUE err = rb_errinfo();
|
61
|
-
if (state == TAG_RAISE &&
|
61
|
+
if (state == TAG_RAISE && RB_TEST(err))
|
62
62
|
{
|
63
63
|
rb_set_errinfo(Qnil);
|
64
64
|
throw Rice::Exception(err);
|
@@ -71,22 +71,10 @@ namespace Rice::detail
|
|
71
71
|
}
|
72
72
|
|
73
73
|
// Create a functor for calling a Ruby function and define some aliases for readability.
|
74
|
-
template<typename
|
75
|
-
|
74
|
+
template<typename Function_T, typename ...Arg_Ts>
|
75
|
+
auto protect(Function_T func, Arg_Ts...args)
|
76
76
|
{
|
77
|
-
|
78
|
-
auto rubyFunction = RubyFunction<Function_T, Return_T, Arg_Ts...>(func, args...);
|
79
|
-
return rubyFunction();
|
80
|
-
}
|
81
|
-
}
|
82
|
-
|
83
|
-
namespace Rice
|
84
|
-
{
|
85
|
-
template<typename Return_T, typename ...Arg_Ts>
|
86
|
-
inline Return_T protect(Return_T(*func)(Arg_Ts...), Arg_Ts...args)
|
87
|
-
{
|
88
|
-
using Function_T = Return_T(*)(Arg_Ts...);
|
89
|
-
auto rubyFunction = detail::RubyFunction<Function_T, Return_T, Arg_Ts...>(func, args...);
|
77
|
+
auto rubyFunction = RubyFunction<Function_T, Arg_Ts...>(func, std::forward<Arg_Ts>(args)...);
|
90
78
|
return rubyFunction();
|
91
79
|
}
|
92
80
|
}
|
data/rice/detail/Type.hpp
CHANGED
data/rice/detail/Type.ipp
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#include "rice_traits.hpp"
|
1
|
+
#include "../traits/rice_traits.hpp"
|
2
2
|
|
3
3
|
#include <iosfwd>
|
4
4
|
#include <iterator>
|
@@ -33,7 +33,7 @@ namespace Rice::detail
|
|
33
33
|
template<typename Tuple_T, size_t...Is>
|
34
34
|
void verifyTypesImpl()
|
35
35
|
{
|
36
|
-
(
|
36
|
+
(verifyType<typename std::tuple_element<Is, Tuple_T>::type>(), ...);
|
37
37
|
}
|
38
38
|
|
39
39
|
template<typename Tuple_T>
|
@@ -9,7 +9,7 @@
|
|
9
9
|
|
10
10
|
#include "ruby.hpp"
|
11
11
|
|
12
|
-
/* The type
|
12
|
+
/* The type registry keeps track of all C++ types wrapped by Rice. When a native function returns
|
13
13
|
an instance of a class/struct we look up its type to verity that it has been registered.
|
14
14
|
|
15
15
|
We have to do this to support C++ inheritance. If a C++ function returns a pointer/reference
|
@@ -22,26 +22,23 @@ namespace Rice::detail
|
|
22
22
|
{
|
23
23
|
public:
|
24
24
|
template <typename T>
|
25
|
-
|
25
|
+
void add(VALUE klass, rb_data_type_t* rbType);
|
26
26
|
|
27
27
|
template <typename T>
|
28
|
-
|
28
|
+
void remove();
|
29
29
|
|
30
30
|
template <typename T>
|
31
|
-
|
31
|
+
bool isDefined();
|
32
32
|
|
33
33
|
template <typename T>
|
34
|
-
|
35
|
-
|
36
|
-
template <typename T>
|
37
|
-
static void verifyDefined();
|
34
|
+
bool verifyDefined();
|
38
35
|
|
39
36
|
template <typename T>
|
40
|
-
|
37
|
+
std::pair<VALUE, rb_data_type_t*> figureType(const T& object);
|
41
38
|
|
42
39
|
private:
|
43
|
-
|
44
|
-
|
40
|
+
std::optional<std::pair<VALUE, rb_data_type_t*>> lookup(const std::type_info& typeInfo);
|
41
|
+
std::unordered_map<std::type_index, std::pair<VALUE, rb_data_type_t*>> registry_{};
|
45
42
|
};
|
46
43
|
}
|
47
44
|
|
@@ -1,18 +1,11 @@
|
|
1
1
|
#include <stdexcept>
|
2
2
|
|
3
3
|
#include "ruby.hpp"
|
4
|
-
#include "rice_traits.hpp"
|
4
|
+
#include "../traits/rice_traits.hpp"
|
5
5
|
#include "Type.hpp"
|
6
6
|
|
7
7
|
namespace Rice::detail
|
8
8
|
{
|
9
|
-
template <typename T>
|
10
|
-
inline void TypeRegistry::add()
|
11
|
-
{
|
12
|
-
std::type_index key(typeid(T));
|
13
|
-
registry_[key] = std::pair(Qnil, nullptr);
|
14
|
-
}
|
15
|
-
|
16
9
|
template <typename T>
|
17
10
|
inline void TypeRegistry::add(VALUE klass, rb_data_type_t* rbType)
|
18
11
|
{
|
@@ -36,13 +29,14 @@ namespace Rice::detail
|
|
36
29
|
}
|
37
30
|
|
38
31
|
template <typename T>
|
39
|
-
inline
|
32
|
+
inline bool TypeRegistry::verifyDefined()
|
40
33
|
{
|
41
34
|
if (!isDefined<T>())
|
42
35
|
{
|
43
36
|
std::string message = "Type is not defined with Rice: " + detail::typeName(typeid(T));
|
44
37
|
throw std::invalid_argument(message);
|
45
38
|
}
|
39
|
+
return true;
|
46
40
|
}
|
47
41
|
|
48
42
|
inline std::optional<std::pair<VALUE, rb_data_type_t*>> TypeRegistry::lookup(const std::type_info& typeInfo)
|
@@ -84,23 +78,4 @@ namespace Rice::detail
|
|
84
78
|
std::string message = "Type " + typeName(typeid(object)) + " is not registered";
|
85
79
|
throw std::runtime_error(message.c_str());
|
86
80
|
}
|
87
|
-
|
88
|
-
// TODO - hacky to put this here but there is a circular dependency between Type and TypeRegistry
|
89
|
-
template<typename T>
|
90
|
-
bool Type<T>::verify()
|
91
|
-
{
|
92
|
-
// Use intrinsic_type so that we don't have to define specializations
|
93
|
-
// for pointers, references, const, etc.
|
94
|
-
using Intrinsic_T = intrinsic_type<T>;
|
95
|
-
|
96
|
-
if constexpr (std::is_fundamental_v<Intrinsic_T>)
|
97
|
-
{
|
98
|
-
return true;
|
99
|
-
}
|
100
|
-
else
|
101
|
-
{
|
102
|
-
TypeRegistry::verifyDefined<Intrinsic_T>();
|
103
|
-
return true;
|
104
|
-
}
|
105
|
-
}
|
106
81
|
}
|
data/rice/detail/Wrapper.hpp
CHANGED