rice 4.0.4 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/Rakefile +1 -1
- data/include/rice/rice.hpp +2596 -1771
- data/include/rice/stl.hpp +1580 -271
- 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 +60 -13
- data/rice/detail/NativeFunction.ipp +103 -85
- 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 +73 -23
- 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/test/embed_ruby.cpp +0 -15
- data/test/test_Array.cpp +20 -24
- 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_Memory_Management.cpp +1 -1
- data/test/test_Module.cpp +25 -62
- data/test/test_Object.cpp +66 -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 +5 -5
- data/test/test_Stl_Unordered_Map.cpp +697 -0
- data/test/test_Stl_Variant.cpp +301 -0
- data/test/test_Stl_Vector.cpp +200 -41
- data/test/test_Struct.cpp +3 -3
- data/test/test_To_From_Ruby.cpp +6 -0
- data/test/test_Tracking.cpp +239 -0
- data/test/unittest.hpp +13 -4
- metadata +23 -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