rice 4.2.1 → 4.3.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 +169 -162
- data/include/rice/rice.hpp +8762 -8672
- data/include/rice/stl.hpp +128 -10
- data/lib/version.rb +3 -3
- data/rice/Data_Object.ipp +386 -313
- data/rice/Data_Type.ipp +1 -0
- data/rice/Identifier.hpp +50 -50
- data/rice/Identifier.ipp +28 -28
- data/rice/detail/NativeFunction.hpp +119 -119
- data/rice/detail/NativeFunction.ipp +300 -300
- data/rice/detail/NativeIterator.hpp +1 -1
- data/rice/detail/NativeIterator.ipp +101 -101
- data/rice/detail/Wrapper.ipp +11 -1
- data/rice/stl.hpp +1 -0
- data/test/embed_ruby.cpp +2 -2
- data/test/test_Array.cpp +301 -301
- data/test/test_Iterator.cpp +356 -290
- data/test/test_Stl_SmartPointer.cpp +45 -2
- data/test/test_Stl_String_View.cpp +88 -0
- data/test/test_Stl_Unordered_Map.cpp +38 -34
- data/test/test_Stl_Vector.cpp +871 -811
- data/test/test_String.cpp +15 -0
- metadata +4 -3
data/rice/Data_Type.ipp
CHANGED
data/rice/Identifier.hpp
CHANGED
@@ -1,50 +1,50 @@
|
|
1
|
-
#ifndef Rice__Identifier__hpp_
|
2
|
-
#define Rice__Identifier__hpp_
|
3
|
-
|
4
|
-
#include <string>
|
5
|
-
|
6
|
-
namespace Rice
|
7
|
-
{
|
8
|
-
class Symbol;
|
9
|
-
|
10
|
-
//! A wrapper for the ID type
|
11
|
-
/*! An ID is ruby's internal representation of a Symbol object.
|
12
|
-
*/
|
13
|
-
class Identifier
|
14
|
-
{
|
15
|
-
public:
|
16
|
-
//! Construct a new Identifier from an ID.
|
17
|
-
Identifier(ID id);
|
18
|
-
|
19
|
-
//! Construct a new Identifier from a Symbol.
|
20
|
-
Identifier(Symbol const& symbol);
|
21
|
-
|
22
|
-
//! Construct a new Identifier from a c string.
|
23
|
-
Identifier(char const* s);
|
24
|
-
|
25
|
-
//! Construct a new Identifier from a string.
|
26
|
-
Identifier(std::string const string);
|
27
|
-
|
28
|
-
//! Return a string representation of the Identifier.
|
29
|
-
char const* c_str() const;
|
30
|
-
|
31
|
-
//! Return a string representation of the Identifier.
|
32
|
-
std::string str() const;
|
33
|
-
|
34
|
-
//! Return the underlying ID
|
35
|
-
ID id() const { return id_; }
|
36
|
-
|
37
|
-
//! Return the underlying ID
|
38
|
-
operator ID() const { return id_; }
|
39
|
-
|
40
|
-
//! Return the ID as a Symbol
|
41
|
-
VALUE to_sym() const;
|
42
|
-
|
43
|
-
private:
|
44
|
-
ID id_;
|
45
|
-
};
|
46
|
-
} // namespace Rice
|
47
|
-
|
48
|
-
#include "Identifier.ipp"
|
49
|
-
|
50
|
-
#endif // Rice__Identifier__hpp_
|
1
|
+
#ifndef Rice__Identifier__hpp_
|
2
|
+
#define Rice__Identifier__hpp_
|
3
|
+
|
4
|
+
#include <string>
|
5
|
+
|
6
|
+
namespace Rice
|
7
|
+
{
|
8
|
+
class Symbol;
|
9
|
+
|
10
|
+
//! A wrapper for the ID type
|
11
|
+
/*! An ID is ruby's internal representation of a Symbol object.
|
12
|
+
*/
|
13
|
+
class Identifier
|
14
|
+
{
|
15
|
+
public:
|
16
|
+
//! Construct a new Identifier from an ID.
|
17
|
+
Identifier(ID id);
|
18
|
+
|
19
|
+
//! Construct a new Identifier from a Symbol.
|
20
|
+
Identifier(Symbol const& symbol);
|
21
|
+
|
22
|
+
//! Construct a new Identifier from a c string.
|
23
|
+
Identifier(char const* s);
|
24
|
+
|
25
|
+
//! Construct a new Identifier from a string.
|
26
|
+
Identifier(std::string const& string);
|
27
|
+
|
28
|
+
//! Return a string representation of the Identifier.
|
29
|
+
char const* c_str() const;
|
30
|
+
|
31
|
+
//! Return a string representation of the Identifier.
|
32
|
+
std::string str() const;
|
33
|
+
|
34
|
+
//! Return the underlying ID
|
35
|
+
ID id() const { return id_; }
|
36
|
+
|
37
|
+
//! Return the underlying ID
|
38
|
+
operator ID() const { return id_; }
|
39
|
+
|
40
|
+
//! Return the ID as a Symbol
|
41
|
+
VALUE to_sym() const;
|
42
|
+
|
43
|
+
private:
|
44
|
+
ID id_;
|
45
|
+
};
|
46
|
+
} // namespace Rice
|
47
|
+
|
48
|
+
#include "Identifier.ipp"
|
49
|
+
|
50
|
+
#endif // Rice__Identifier__hpp_
|
data/rice/Identifier.ipp
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
namespace Rice
|
2
|
-
{
|
3
|
-
inline Identifier::Identifier(ID id) : id_(id)
|
4
|
-
{
|
5
|
-
}
|
6
|
-
|
7
|
-
inline Identifier::Identifier(char const* s) : id_(rb_intern(s))
|
8
|
-
{
|
9
|
-
}
|
10
|
-
|
11
|
-
inline Identifier::Identifier(std::string const s) : id_(
|
12
|
-
{
|
13
|
-
}
|
14
|
-
|
15
|
-
inline char const* Identifier::c_str() const
|
16
|
-
{
|
17
|
-
return detail::protect(rb_id2name, id_);
|
18
|
-
}
|
19
|
-
|
20
|
-
inline std::string Identifier::str() const
|
21
|
-
{
|
22
|
-
return c_str();
|
23
|
-
}
|
24
|
-
|
25
|
-
inline VALUE Identifier::to_sym() const
|
26
|
-
{
|
27
|
-
return ID2SYM(id_);
|
28
|
-
}
|
1
|
+
namespace Rice
|
2
|
+
{
|
3
|
+
inline Identifier::Identifier(ID id) : id_(id)
|
4
|
+
{
|
5
|
+
}
|
6
|
+
|
7
|
+
inline Identifier::Identifier(char const* s) : id_(rb_intern(s))
|
8
|
+
{
|
9
|
+
}
|
10
|
+
|
11
|
+
inline Identifier::Identifier(std::string const& s) : id_(rb_intern2(s.c_str(), s.size()))
|
12
|
+
{
|
13
|
+
}
|
14
|
+
|
15
|
+
inline char const* Identifier::c_str() const
|
16
|
+
{
|
17
|
+
return detail::protect(rb_id2name, id_);
|
18
|
+
}
|
19
|
+
|
20
|
+
inline std::string Identifier::str() const
|
21
|
+
{
|
22
|
+
return c_str();
|
23
|
+
}
|
24
|
+
|
25
|
+
inline VALUE Identifier::to_sym() const
|
26
|
+
{
|
27
|
+
return ID2SYM(id_);
|
28
|
+
}
|
29
29
|
}
|
@@ -1,119 +1,119 @@
|
|
1
|
-
#ifndef Rice__detail__Native_Function__hpp_
|
2
|
-
#define Rice__detail__Native_Function__hpp_
|
3
|
-
|
4
|
-
#include "ruby.hpp"
|
5
|
-
#include "ExceptionHandler_defn.hpp"
|
6
|
-
#include "MethodInfo.hpp"
|
7
|
-
#include "../traits/function_traits.hpp"
|
8
|
-
#include "../traits/method_traits.hpp"
|
9
|
-
#include "from_ruby.hpp"
|
10
|
-
|
11
|
-
namespace Rice::detail
|
12
|
-
{
|
13
|
-
//! The NativeFunction class calls C++ functions/methods/lambdas on behalf of Ruby
|
14
|
-
/*! The NativeFunction class is an intermediate between Ruby and C++. Every method
|
15
|
-
* defined in Rice is associated with a NativeFuntion instance that is stored in
|
16
|
-
* a unordered_map maintained by the MethodData class. The key is the Ruby class
|
17
|
-
* and method.
|
18
|
-
*
|
19
|
-
* When Ruby calls into C++ it invokes the static NativeFunction.call method. This
|
20
|
-
* method then looks up the NativeFunction instance and calls its ->() operator.
|
21
|
-
*
|
22
|
-
* The instance then converts each of the arguments passed from Ruby into their
|
23
|
-
* C++ equivalents. It then retrieves the C++ object (if there is one, Ruby could
|
24
|
-
* be calling a free standing method or lambda). Then it calls the C++ method
|
25
|
-
* and gets back the result. If there is a result (so not void), it is converted
|
26
|
-
* from a C++ object to a Ruby object and returned back to Ruby.
|
27
|
-
*
|
28
|
-
* This class make heavy use of C++ Template metaprogramming to determine
|
29
|
-
* the types and parameters a method takes. It then uses that information
|
30
|
-
* to perform type conversion Ruby to C++.
|
31
|
-
*
|
32
|
-
* @tparam
|
33
|
-
*
|
34
|
-
* std::map has a size() method but that is actually implemented on
|
35
|
-
*
|
36
|
-
*
|
37
|
-
*
|
38
|
-
* @tparam Function_T - A template that represents the C++ function
|
39
|
-
* to call. This typename is automatically deduced by the compiler.
|
40
|
-
* @tparam IsMethod - A boolean specifying whether the function has
|
41
|
-
* a self parameter or not. Rice differentiates these two cases by
|
42
|
-
* calling them methods (self) or functions (no self).
|
43
|
-
*/
|
44
|
-
|
45
|
-
template<typename
|
46
|
-
class NativeFunction
|
47
|
-
{
|
48
|
-
public:
|
49
|
-
using NativeFunction_T = NativeFunction<
|
50
|
-
|
51
|
-
// We remove const to avoid an explosion of To_Ruby specializations and Ruby doesn't
|
52
|
-
// have the concept of constants anyways
|
53
|
-
using Return_T = remove_cv_recursive_t<typename function_traits<Function_T>::return_type>;
|
54
|
-
using
|
55
|
-
using Arg_Ts = typename method_traits<Function_T, IsMethod>::Arg_Ts;
|
56
|
-
using From_Ruby_Args_Ts = typename tuple_map<From_Ruby, Arg_Ts>::type;
|
57
|
-
|
58
|
-
// Register function with Ruby
|
59
|
-
static void define(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
|
60
|
-
|
61
|
-
// Static member function that Ruby calls
|
62
|
-
static VALUE call(int argc, VALUE* argv, VALUE self);
|
63
|
-
|
64
|
-
public:
|
65
|
-
// Disallow creating/copying/moving
|
66
|
-
NativeFunction() = delete;
|
67
|
-
NativeFunction(const NativeFunction_T&) = delete;
|
68
|
-
NativeFunction(NativeFunction_T&&) = delete;
|
69
|
-
void operator=(const NativeFunction_T&) = delete;
|
70
|
-
void operator=(NativeFunction_T&&) = delete;
|
71
|
-
|
72
|
-
// Invokes the wrapped function
|
73
|
-
VALUE operator()(int argc, VALUE* argv, VALUE self);
|
74
|
-
|
75
|
-
protected:
|
76
|
-
NativeFunction(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
|
77
|
-
|
78
|
-
private:
|
79
|
-
template<typename T, std::size_t I>
|
80
|
-
From_Ruby<T> createFromRuby();
|
81
|
-
|
82
|
-
// Create NativeArgs which are used to convert values from Ruby to C++
|
83
|
-
template<std::size_t...I>
|
84
|
-
From_Ruby_Args_Ts createFromRuby(std::index_sequence<I...>& indices);
|
85
|
-
|
86
|
-
To_Ruby<Return_T> createToRuby();
|
87
|
-
|
88
|
-
// Convert Ruby argv pointer to Ruby values
|
89
|
-
std::vector<VALUE> getRubyValues(int argc, VALUE* argv);
|
90
|
-
|
91
|
-
// Convert Ruby values to C++ values
|
92
|
-
template<typename std::size_t...I>
|
93
|
-
Arg_Ts getNativeValues(std::vector<VALUE>& values, std::index_sequence<I...>& indices);
|
94
|
-
|
95
|
-
// Figure out what self is
|
96
|
-
|
97
|
-
|
98
|
-
// Throw an exception when wrapper cannot be extracted
|
99
|
-
[[noreturn]] void noWrapper(const VALUE klass, const std::string& wrapper);
|
100
|
-
|
101
|
-
// Do we need to keep alive any arguments?
|
102
|
-
void checkKeepAlive(VALUE self, VALUE returnValue, std::vector<VALUE>& rubyValues);
|
103
|
-
|
104
|
-
// Call the underlying C++ function
|
105
|
-
VALUE invokeNativeFunction(const Arg_Ts& nativeArgs);
|
106
|
-
VALUE invokeNativeMethod(VALUE self, const Arg_Ts& nativeArgs);
|
107
|
-
|
108
|
-
private:
|
109
|
-
VALUE klass_;
|
110
|
-
std::string method_name_;
|
111
|
-
Function_T function_;
|
112
|
-
From_Ruby_Args_Ts fromRubys_;
|
113
|
-
To_Ruby<Return_T> toRuby_;
|
114
|
-
std::unique_ptr<MethodInfo> methodInfo_;
|
115
|
-
};
|
116
|
-
}
|
117
|
-
#include "NativeFunction.ipp"
|
118
|
-
|
119
|
-
#endif // Rice__detail__Native_Function__hpp_
|
1
|
+
#ifndef Rice__detail__Native_Function__hpp_
|
2
|
+
#define Rice__detail__Native_Function__hpp_
|
3
|
+
|
4
|
+
#include "ruby.hpp"
|
5
|
+
#include "ExceptionHandler_defn.hpp"
|
6
|
+
#include "MethodInfo.hpp"
|
7
|
+
#include "../traits/function_traits.hpp"
|
8
|
+
#include "../traits/method_traits.hpp"
|
9
|
+
#include "from_ruby.hpp"
|
10
|
+
|
11
|
+
namespace Rice::detail
|
12
|
+
{
|
13
|
+
//! The NativeFunction class calls C++ functions/methods/lambdas on behalf of Ruby
|
14
|
+
/*! The NativeFunction class is an intermediate between Ruby and C++. Every method
|
15
|
+
* defined in Rice is associated with a NativeFuntion instance that is stored in
|
16
|
+
* a unordered_map maintained by the MethodData class. The key is the Ruby class
|
17
|
+
* and method.
|
18
|
+
*
|
19
|
+
* When Ruby calls into C++ it invokes the static NativeFunction.call method. This
|
20
|
+
* method then looks up the NativeFunction instance and calls its ->() operator.
|
21
|
+
*
|
22
|
+
* The instance then converts each of the arguments passed from Ruby into their
|
23
|
+
* C++ equivalents. It then retrieves the C++ object (if there is one, Ruby could
|
24
|
+
* be calling a free standing method or lambda). Then it calls the C++ method
|
25
|
+
* and gets back the result. If there is a result (so not void), it is converted
|
26
|
+
* from a C++ object to a Ruby object and returned back to Ruby.
|
27
|
+
*
|
28
|
+
* This class make heavy use of C++ Template metaprogramming to determine
|
29
|
+
* the types and parameters a method takes. It then uses that information
|
30
|
+
* to perform type conversion Ruby to C++.
|
31
|
+
*
|
32
|
+
* @tparam Receiver_T - The type of C++ class wrapped by Ruby. Althought NativeFunction
|
33
|
+
* can derive the C++ class (Receiver_T), it can differ per member function. For example,
|
34
|
+
* std::map has a size() method but that is actually implemented on an ancestor class _Tree.
|
35
|
+
* Thus Receiver_T is std::map but Function_T::Receiver_T is _Tree. This breaks Rice in two ways.
|
36
|
+
* First, _Tree is not a registered type. Second, Rice would return a _Tree instance back to
|
37
|
+
* C++ and not a std::map.
|
38
|
+
* @tparam Function_T - A template that represents the C++ function
|
39
|
+
* to call. This typename is automatically deduced by the compiler.
|
40
|
+
* @tparam IsMethod - A boolean specifying whether the function has
|
41
|
+
* a self parameter or not. Rice differentiates these two cases by
|
42
|
+
* calling them methods (self) or functions (no self).
|
43
|
+
*/
|
44
|
+
|
45
|
+
template<typename Class_T, typename Function_T, bool IsMethod>
|
46
|
+
class NativeFunction
|
47
|
+
{
|
48
|
+
public:
|
49
|
+
using NativeFunction_T = NativeFunction<Class_T, Function_T, IsMethod>;
|
50
|
+
|
51
|
+
// We remove const to avoid an explosion of To_Ruby specializations and Ruby doesn't
|
52
|
+
// have the concept of constants anyways
|
53
|
+
using Return_T = remove_cv_recursive_t<typename function_traits<Function_T>::return_type>;
|
54
|
+
using Receiver_T = typename method_traits<Function_T, IsMethod>::Class_T;
|
55
|
+
using Arg_Ts = typename method_traits<Function_T, IsMethod>::Arg_Ts;
|
56
|
+
using From_Ruby_Args_Ts = typename tuple_map<From_Ruby, Arg_Ts>::type;
|
57
|
+
|
58
|
+
// Register function with Ruby
|
59
|
+
static void define(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
|
60
|
+
|
61
|
+
// Static member function that Ruby calls
|
62
|
+
static VALUE call(int argc, VALUE* argv, VALUE self);
|
63
|
+
|
64
|
+
public:
|
65
|
+
// Disallow creating/copying/moving
|
66
|
+
NativeFunction() = delete;
|
67
|
+
NativeFunction(const NativeFunction_T&) = delete;
|
68
|
+
NativeFunction(NativeFunction_T&&) = delete;
|
69
|
+
void operator=(const NativeFunction_T&) = delete;
|
70
|
+
void operator=(NativeFunction_T&&) = delete;
|
71
|
+
|
72
|
+
// Invokes the wrapped function
|
73
|
+
VALUE operator()(int argc, VALUE* argv, VALUE self);
|
74
|
+
|
75
|
+
protected:
|
76
|
+
NativeFunction(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
|
77
|
+
|
78
|
+
private:
|
79
|
+
template<typename T, std::size_t I>
|
80
|
+
From_Ruby<T> createFromRuby();
|
81
|
+
|
82
|
+
// Create NativeArgs which are used to convert values from Ruby to C++
|
83
|
+
template<std::size_t...I>
|
84
|
+
From_Ruby_Args_Ts createFromRuby(std::index_sequence<I...>& indices);
|
85
|
+
|
86
|
+
To_Ruby<Return_T> createToRuby();
|
87
|
+
|
88
|
+
// Convert Ruby argv pointer to Ruby values
|
89
|
+
std::vector<VALUE> getRubyValues(int argc, VALUE* argv);
|
90
|
+
|
91
|
+
// Convert Ruby values to C++ values
|
92
|
+
template<typename std::size_t...I>
|
93
|
+
Arg_Ts getNativeValues(std::vector<VALUE>& values, std::index_sequence<I...>& indices);
|
94
|
+
|
95
|
+
// Figure out what self is
|
96
|
+
Receiver_T getReceiver(VALUE self);
|
97
|
+
|
98
|
+
// Throw an exception when wrapper cannot be extracted
|
99
|
+
[[noreturn]] void noWrapper(const VALUE klass, const std::string& wrapper);
|
100
|
+
|
101
|
+
// Do we need to keep alive any arguments?
|
102
|
+
void checkKeepAlive(VALUE self, VALUE returnValue, std::vector<VALUE>& rubyValues);
|
103
|
+
|
104
|
+
// Call the underlying C++ function
|
105
|
+
VALUE invokeNativeFunction(const Arg_Ts& nativeArgs);
|
106
|
+
VALUE invokeNativeMethod(VALUE self, const Arg_Ts& nativeArgs);
|
107
|
+
|
108
|
+
private:
|
109
|
+
VALUE klass_;
|
110
|
+
std::string method_name_;
|
111
|
+
Function_T function_;
|
112
|
+
From_Ruby_Args_Ts fromRubys_;
|
113
|
+
To_Ruby<Return_T> toRuby_;
|
114
|
+
std::unique_ptr<MethodInfo> methodInfo_;
|
115
|
+
};
|
116
|
+
}
|
117
|
+
#include "NativeFunction.ipp"
|
118
|
+
|
119
|
+
#endif // Rice__detail__Native_Function__hpp_
|