rice 4.2.1 → 4.3.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 +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_
|