rice 4.5.0 → 4.6.1
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 +33 -0
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/Rakefile +5 -4
- data/include/rice/rice.hpp +5619 -3129
- data/include/rice/stl.hpp +2319 -1234
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +4 -0
- data/lib/rice/version.rb +3 -0
- data/lib/rice.rb +1 -0
- data/lib/rubygems/builder.rb +11 -0
- data/lib/rubygems/cmake_builder.rb +113 -0
- data/lib/rubygems_plugin.rb +9 -0
- data/rice/Arg.hpp +7 -1
- data/rice/Arg.ipp +11 -2
- data/rice/Buffer.hpp +168 -0
- data/rice/Buffer.ipp +788 -0
- data/rice/Constructor.ipp +3 -3
- data/rice/Data_Object.hpp +2 -3
- data/rice/Data_Object.ipp +188 -188
- data/rice/Data_Type.hpp +7 -5
- data/rice/Data_Type.ipp +79 -52
- data/rice/Enum.hpp +0 -1
- data/rice/Enum.ipp +26 -23
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/MemoryView.ipp +1 -41
- data/rice/Return.hpp +1 -1
- data/rice/Return.ipp +6 -0
- data/rice/cpp_api/Array.hpp +209 -0
- data/rice/cpp_api/Array.ipp +304 -0
- data/rice/cpp_api/Builtin_Object.hpp +31 -0
- data/rice/cpp_api/Builtin_Object.ipp +37 -0
- data/rice/cpp_api/Class.hpp +70 -0
- data/rice/cpp_api/Class.ipp +97 -0
- data/rice/cpp_api/Encoding.hpp +32 -0
- data/rice/cpp_api/Encoding.ipp +59 -0
- data/rice/cpp_api/Hash.hpp +194 -0
- data/rice/cpp_api/Hash.ipp +257 -0
- data/rice/cpp_api/Identifier.hpp +46 -0
- data/rice/cpp_api/Identifier.ipp +31 -0
- data/rice/cpp_api/Module.hpp +72 -0
- data/rice/cpp_api/Module.ipp +101 -0
- data/rice/cpp_api/Object.hpp +272 -0
- data/rice/cpp_api/Object.ipp +235 -0
- data/rice/cpp_api/String.hpp +74 -0
- data/rice/cpp_api/String.ipp +120 -0
- data/rice/cpp_api/Struct.hpp +113 -0
- data/rice/cpp_api/Struct.ipp +92 -0
- data/rice/cpp_api/Symbol.hpp +46 -0
- data/rice/cpp_api/Symbol.ipp +93 -0
- data/rice/cpp_api/shared_methods.hpp +134 -0
- data/rice/detail/MethodInfo.hpp +1 -9
- data/rice/detail/MethodInfo.ipp +5 -72
- data/rice/detail/Native.hpp +3 -2
- data/rice/detail/Native.ipp +32 -4
- data/rice/detail/NativeAttributeGet.hpp +3 -2
- data/rice/detail/NativeAttributeGet.ipp +20 -3
- data/rice/detail/NativeAttributeSet.hpp +3 -2
- data/rice/detail/NativeAttributeSet.ipp +11 -23
- data/rice/detail/NativeCallbackFFI.ipp +2 -1
- data/rice/detail/NativeFunction.hpp +17 -6
- data/rice/detail/NativeFunction.ipp +169 -64
- data/rice/detail/NativeIterator.hpp +3 -2
- data/rice/detail/NativeIterator.ipp +8 -2
- data/rice/detail/RubyFunction.ipp +1 -0
- data/rice/detail/RubyType.hpp +2 -5
- data/rice/detail/RubyType.ipp +50 -5
- data/rice/detail/Type.hpp +3 -1
- data/rice/detail/Type.ipp +60 -31
- data/rice/detail/Wrapper.hpp +68 -33
- data/rice/detail/Wrapper.ipp +103 -113
- data/rice/detail/from_ruby.hpp +5 -4
- data/rice/detail/from_ruby.ipp +737 -365
- data/rice/detail/to_ruby.ipp +1092 -186
- data/rice/global_function.ipp +1 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +23 -16
- data/rice/stl/complex.hpp +6 -0
- data/rice/stl/complex.ipp +93 -0
- data/rice/stl/exception.hpp +11 -0
- data/rice/stl/exception.ipp +29 -0
- data/rice/stl/exception_ptr.hpp +6 -0
- data/rice/stl/exception_ptr.ipp +27 -0
- data/rice/stl/map.hpp +12 -0
- data/rice/stl/map.ipp +469 -0
- data/rice/stl/monostate.hpp +6 -0
- data/rice/stl/monostate.ipp +80 -0
- data/rice/stl/multimap.hpp +14 -0
- data/rice/stl/multimap.ipp +448 -0
- data/rice/stl/optional.hpp +6 -0
- data/rice/stl/optional.ipp +118 -0
- data/rice/stl/pair.hpp +13 -0
- data/rice/stl/pair.ipp +155 -0
- data/rice/stl/reference_wrapper.hpp +6 -0
- data/rice/stl/reference_wrapper.ipp +41 -0
- data/rice/stl/set.hpp +12 -0
- data/rice/stl/set.ipp +495 -0
- data/rice/stl/shared_ptr.hpp +28 -0
- data/rice/stl/shared_ptr.ipp +224 -0
- data/rice/stl/string.hpp +6 -0
- data/rice/stl/string.ipp +158 -0
- data/rice/stl/string_view.hpp +6 -0
- data/rice/stl/string_view.ipp +65 -0
- data/rice/stl/tuple.hpp +6 -0
- data/rice/stl/tuple.ipp +128 -0
- data/rice/stl/type_index.hpp +6 -0
- data/rice/stl/type_index.ipp +30 -0
- data/rice/stl/type_info.hpp +6 -0
- data/rice/stl/type_info.ipp +29 -0
- data/rice/stl/unique_ptr.hpp +22 -0
- data/rice/stl/unique_ptr.ipp +139 -0
- data/rice/stl/unordered_map.hpp +12 -0
- data/rice/stl/unordered_map.ipp +469 -0
- data/rice/stl/variant.hpp +6 -0
- data/rice/stl/variant.ipp +242 -0
- data/rice/stl/vector.hpp +12 -0
- data/rice/stl/vector.ipp +589 -0
- data/rice/stl.hpp +7 -3
- data/rice/traits/attribute_traits.hpp +26 -0
- data/rice/traits/function_traits.hpp +95 -0
- data/rice/traits/method_traits.hpp +47 -0
- data/rice/traits/rice_traits.hpp +172 -0
- data/rice.gemspec +85 -0
- data/test/embed_ruby.cpp +3 -0
- data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
- data/test/test_Array.cpp +6 -3
- data/test/test_Attribute.cpp +91 -9
- data/test/test_Buffer.cpp +340 -0
- data/test/test_Callback.cpp +2 -3
- data/test/test_Data_Object.cpp +88 -34
- data/test/test_Data_Type.cpp +106 -65
- data/test/test_Director.cpp +7 -3
- data/test/test_Enum.cpp +5 -2
- data/test/test_File.cpp +1 -1
- data/test/test_From_Ruby.cpp +180 -113
- data/test/test_Iterator.cpp +1 -1
- data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
- data/test/test_Keep_Alive.cpp +7 -18
- data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
- data/test/test_Module.cpp +13 -6
- data/test/test_Native_Registry.cpp +0 -1
- data/test/test_Overloads.cpp +180 -5
- data/test/test_Ownership.cpp +100 -57
- data/test/test_Proc.cpp +0 -1
- data/test/test_Self.cpp +4 -4
- data/test/test_Stl_Map.cpp +37 -39
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Pair.cpp +8 -8
- data/test/test_Stl_Reference_Wrapper.cpp +4 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +28 -34
- data/test/test_Stl_Variant.cpp +217 -89
- data/test/test_Stl_Vector.cpp +209 -83
- data/test/test_To_Ruby.cpp +373 -1
- data/test/test_Type.cpp +85 -14
- data/test/test_global_functions.cpp +17 -4
- metadata +94 -10
- data/rice/detail/TupleIterator.hpp +0 -14
@@ -0,0 +1,95 @@
|
|
1
|
+
#ifndef Rice__detail__function_traits__hpp_
|
2
|
+
#define Rice__detail__function_traits__hpp_
|
3
|
+
|
4
|
+
#include <tuple>
|
5
|
+
|
6
|
+
namespace Rice::detail
|
7
|
+
{
|
8
|
+
// Base class
|
9
|
+
template<typename Function_T>
|
10
|
+
struct function_traits;
|
11
|
+
|
12
|
+
template<typename Return_T, typename Class_T, typename...Arg_Ts>
|
13
|
+
struct function_traits<Return_T(Class_T, Arg_Ts...)>
|
14
|
+
{
|
15
|
+
using arg_types = std::tuple<Arg_Ts...>;
|
16
|
+
|
17
|
+
static constexpr std::size_t arity = sizeof...(Arg_Ts);
|
18
|
+
|
19
|
+
template<std::size_t N>
|
20
|
+
using nth_arg = typename std::tuple_element<N, arg_types>::type;
|
21
|
+
|
22
|
+
using return_type = Return_T;
|
23
|
+
using class_type = Class_T;
|
24
|
+
};
|
25
|
+
|
26
|
+
// Functors and lambdas with operator()
|
27
|
+
template<typename Function_T>
|
28
|
+
struct function_traits : public function_traits<decltype(&Function_T::operator())>
|
29
|
+
{
|
30
|
+
private:
|
31
|
+
using functor_t = function_traits<decltype(&Function_T::operator())>;
|
32
|
+
|
33
|
+
public:
|
34
|
+
using arg_types = typename functor_t::arg_types;
|
35
|
+
static constexpr std::size_t arity = functor_t::arity - 1;
|
36
|
+
using class_type = std::nullptr_t;
|
37
|
+
};
|
38
|
+
|
39
|
+
// C functions and static member functions passed by pointer
|
40
|
+
template<typename Return_T, typename ...Arg_Ts>
|
41
|
+
struct function_traits<Return_T(*)(Arg_Ts...)> : public function_traits<Return_T(std::nullptr_t, Arg_Ts...)>
|
42
|
+
{
|
43
|
+
using Function_T = Return_T(*)(Arg_Ts...);
|
44
|
+
};
|
45
|
+
|
46
|
+
// C functions passed by pointer that take one or more defined parameter than a variable
|
47
|
+
// number of parameters (the second ...)
|
48
|
+
template<typename Return_T, typename ...Arg_Ts>
|
49
|
+
struct function_traits<Return_T(*)(Arg_Ts..., ...)> : public function_traits<Return_T(std::nullptr_t, Arg_Ts...)>
|
50
|
+
{
|
51
|
+
};
|
52
|
+
|
53
|
+
// C Functions or static member functions passed by reference
|
54
|
+
template<typename Return_T, typename ...Arg_Ts>
|
55
|
+
struct function_traits<Return_T(&)(Arg_Ts...)> : public function_traits<Return_T(std::nullptr_t, Arg_Ts...)>
|
56
|
+
{
|
57
|
+
};
|
58
|
+
|
59
|
+
// Member Functions on C++ classes
|
60
|
+
template<typename Return_T, typename Class_T, typename...Arg_Ts>
|
61
|
+
struct function_traits<Return_T(Class_T::*)(Arg_Ts...)> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
|
62
|
+
{
|
63
|
+
};
|
64
|
+
|
65
|
+
// const member Functions on C++ classes
|
66
|
+
template<typename Return_T, typename Class_T, typename...Arg_Ts>
|
67
|
+
struct function_traits<Return_T(Class_T::*)(Arg_Ts...) const> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
|
68
|
+
{
|
69
|
+
};
|
70
|
+
|
71
|
+
// noexcept member Functions on C++ classes
|
72
|
+
template<typename Return_T, typename Class_T, typename...Arg_Ts>
|
73
|
+
struct function_traits<Return_T(Class_T::*)(Arg_Ts...) noexcept> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
|
74
|
+
{
|
75
|
+
};
|
76
|
+
|
77
|
+
|
78
|
+
// const noexcept member Functions on C++ classes
|
79
|
+
template<typename Return_T, typename Class_T, typename...Arg_Ts>
|
80
|
+
struct function_traits<Return_T(Class_T::*)(Arg_Ts...) const noexcept> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
|
81
|
+
{
|
82
|
+
};
|
83
|
+
|
84
|
+
/*// Functors and lambdas
|
85
|
+
template<class Function_T>
|
86
|
+
struct function_traits<Function_T&> : public function_traits<Function_T>
|
87
|
+
{
|
88
|
+
};
|
89
|
+
|
90
|
+
template<class Function_T>
|
91
|
+
struct function_traits<Function_T&&> : public function_traits<Function_T>
|
92
|
+
{
|
93
|
+
};*/
|
94
|
+
}
|
95
|
+
#endif // Rice__detail__function_traits__hpp_
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#ifndef Rice__detail__method_traits__hpp_
|
2
|
+
#define Rice__detail__method_traits__hpp_
|
3
|
+
|
4
|
+
#include <tuple>
|
5
|
+
|
6
|
+
namespace Rice::detail
|
7
|
+
{
|
8
|
+
// Declare struct
|
9
|
+
template<typename Function_T, bool IsMethod, typename = void>
|
10
|
+
struct method_traits;
|
11
|
+
|
12
|
+
// Functions that do not have a self parameter:
|
13
|
+
// doSomething(int a)
|
14
|
+
template<typename Function_T, bool IsMethod>
|
15
|
+
struct method_traits<Function_T, IsMethod, std::enable_if_t<!IsMethod>>
|
16
|
+
{
|
17
|
+
using Return_T = typename function_traits<Function_T>::return_type;
|
18
|
+
using Class_T = std::nullptr_t;
|
19
|
+
using Arg_Ts = typename function_traits<Function_T>::arg_types;
|
20
|
+
static constexpr std::size_t arity = std::tuple_size_v<Arg_Ts>;
|
21
|
+
};
|
22
|
+
|
23
|
+
/* Functions that have a self parameter and thus we treat them as free standing
|
24
|
+
"methods" versus member functions.
|
25
|
+
|
26
|
+
doSomething(VALUE self, int a) */
|
27
|
+
template<typename Function_T, bool IsMethod>
|
28
|
+
struct method_traits<Function_T, IsMethod, std::enable_if_t<IsMethod && std::is_same_v<typename function_traits<Function_T>::class_type, std::nullptr_t>>>
|
29
|
+
{
|
30
|
+
using Return_T = typename function_traits<Function_T>::return_type;
|
31
|
+
using Class_T = typename function_traits<Function_T>::template nth_arg<0>;
|
32
|
+
using Arg_Ts = typename tuple_shift<typename function_traits<Function_T>::arg_types>::type;
|
33
|
+
static constexpr std::size_t arity = std::tuple_size_v<Arg_Ts>;
|
34
|
+
};
|
35
|
+
|
36
|
+
// Member functions that have an implied self parameter of an object instance
|
37
|
+
// foo.doSomething(int a)
|
38
|
+
template<typename Function_T, bool IsMethod>
|
39
|
+
struct method_traits<Function_T, IsMethod, std::enable_if_t<IsMethod && !std::is_same_v<typename function_traits<Function_T>::class_type, std::nullptr_t>>>
|
40
|
+
{
|
41
|
+
using Return_T = typename function_traits<Function_T>::return_type;
|
42
|
+
using Class_T = typename function_traits<Function_T>::class_type;
|
43
|
+
using Arg_Ts = typename function_traits<Function_T>::arg_types;
|
44
|
+
static constexpr std::size_t arity = std::tuple_size_v<Arg_Ts>;
|
45
|
+
};
|
46
|
+
}
|
47
|
+
#endif // Rice__detail__method_traits__hpp_
|
@@ -0,0 +1,172 @@
|
|
1
|
+
#ifndef Rice__detail__traits__hpp_
|
2
|
+
#define Rice__detail__traits__hpp_
|
3
|
+
|
4
|
+
#include <ostream>
|
5
|
+
#include <tuple>
|
6
|
+
#include <type_traits>
|
7
|
+
#include <variant>
|
8
|
+
#include <vector>
|
9
|
+
|
10
|
+
namespace Rice
|
11
|
+
{
|
12
|
+
namespace detail
|
13
|
+
{
|
14
|
+
// Get the base_type of T - without pointer, reference, const or volatile. We call remove_pointer_t twice
|
15
|
+
// for T**
|
16
|
+
template<typename T>
|
17
|
+
using intrinsic_type = typename std::remove_cv_t<std::remove_pointer_t<std::remove_pointer_t<std::remove_reference_t<T>>>>;
|
18
|
+
|
19
|
+
template<typename T>
|
20
|
+
constexpr bool is_const_any_v = std::is_const_v<std::remove_pointer_t<std::remove_pointer_t<std::remove_reference_t<T>>>>;
|
21
|
+
|
22
|
+
// Recursively remove const/volatile
|
23
|
+
template<typename T>
|
24
|
+
struct remove_cv_recursive
|
25
|
+
{
|
26
|
+
using type = T;
|
27
|
+
};
|
28
|
+
|
29
|
+
template<typename T>
|
30
|
+
struct remove_cv_recursive<T const volatile>
|
31
|
+
{
|
32
|
+
using type = typename remove_cv_recursive<T>::type;
|
33
|
+
};
|
34
|
+
|
35
|
+
template<typename T>
|
36
|
+
struct remove_cv_recursive<T volatile>
|
37
|
+
{
|
38
|
+
using type = typename remove_cv_recursive<T>::type;
|
39
|
+
};
|
40
|
+
|
41
|
+
template<typename T>
|
42
|
+
struct remove_cv_recursive<T const>
|
43
|
+
{
|
44
|
+
using type = typename remove_cv_recursive<T>::type;
|
45
|
+
};
|
46
|
+
|
47
|
+
template<typename T>
|
48
|
+
struct remove_cv_recursive<T&>
|
49
|
+
{
|
50
|
+
using type = typename remove_cv_recursive<T>::type&;
|
51
|
+
};
|
52
|
+
|
53
|
+
/* template<typename T>
|
54
|
+
struct remove_cv_recursive<T&&>
|
55
|
+
{
|
56
|
+
using type = typename remove_cv_recursive<T>::type&&;
|
57
|
+
};*/
|
58
|
+
|
59
|
+
template<typename T>
|
60
|
+
struct remove_cv_recursive<T*>
|
61
|
+
{
|
62
|
+
using type = typename remove_cv_recursive<T>::type*;
|
63
|
+
};
|
64
|
+
|
65
|
+
template<typename T>
|
66
|
+
using remove_cv_recursive_t = typename remove_cv_recursive<T>::type;
|
67
|
+
|
68
|
+
// Does the Type work with ostreams? This is used to implement #to_s
|
69
|
+
template<typename T, typename = void>
|
70
|
+
struct is_ostreamable : std::false_type {};
|
71
|
+
|
72
|
+
template<typename T>
|
73
|
+
struct is_ostreamable<T, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<const T>())>> : std::true_type {};
|
74
|
+
|
75
|
+
template<typename T>
|
76
|
+
constexpr bool is_ostreamable_v = is_ostreamable<T>::value;
|
77
|
+
|
78
|
+
// Is the type comparable?
|
79
|
+
template<typename T, typename SFINAE = void>
|
80
|
+
struct is_comparable : std::false_type {};
|
81
|
+
|
82
|
+
template<typename T>
|
83
|
+
struct is_comparable<T, std::void_t<
|
84
|
+
// Does the class implement operator== and does it return a boolean value?
|
85
|
+
decltype(std::declval<T>() == std::declval<T>() && true)
|
86
|
+
>> : std::true_type {};
|
87
|
+
|
88
|
+
template<typename T>
|
89
|
+
constexpr bool is_comparable_v = is_comparable<T>::value;
|
90
|
+
|
91
|
+
template <typename U, typename V>
|
92
|
+
struct is_comparable<std::pair<U, V>>
|
93
|
+
{
|
94
|
+
static const bool value = is_comparable_v<U> && is_comparable_v<V>;
|
95
|
+
};
|
96
|
+
|
97
|
+
template <typename T>
|
98
|
+
struct is_comparable<std::vector<T>>
|
99
|
+
{
|
100
|
+
static const bool value = is_comparable_v<T>;
|
101
|
+
};
|
102
|
+
|
103
|
+
// -- Tuple Helpers ---
|
104
|
+
template<typename T>
|
105
|
+
struct tuple_shift;
|
106
|
+
|
107
|
+
template<typename T, typename...Arg_Ts>
|
108
|
+
struct tuple_shift<std::tuple<T, Arg_Ts...>>
|
109
|
+
{
|
110
|
+
using type = std::tuple<Arg_Ts...>;
|
111
|
+
};
|
112
|
+
|
113
|
+
template<template<typename, typename...> typename T, typename...Arg_Ts>
|
114
|
+
struct tuple_map;
|
115
|
+
|
116
|
+
template<template<typename, typename...> typename T, typename...Arg_Ts>
|
117
|
+
struct tuple_map<T, std::tuple<Arg_Ts...>>
|
118
|
+
{
|
119
|
+
using type = std::tuple<T<remove_cv_recursive_t<Arg_Ts>>...>;
|
120
|
+
};
|
121
|
+
|
122
|
+
template<typename...Arg_Ts>
|
123
|
+
struct tuple_to_variant;
|
124
|
+
|
125
|
+
template<typename...Arg_Ts>
|
126
|
+
struct tuple_to_variant<std::tuple<Arg_Ts...>>
|
127
|
+
{
|
128
|
+
using type = std::variant<Arg_Ts...>;
|
129
|
+
};
|
130
|
+
|
131
|
+
template<class T>
|
132
|
+
struct is_pointer_pointer : std::false_type {};
|
133
|
+
|
134
|
+
template<class T>
|
135
|
+
struct is_pointer_pointer<T**> : std::true_type {};
|
136
|
+
|
137
|
+
template<class T>
|
138
|
+
struct is_pointer_pointer<T** const> : std::true_type {};
|
139
|
+
|
140
|
+
template<class T>
|
141
|
+
struct is_pointer_pointer<T* const * const> : std::true_type {};
|
142
|
+
|
143
|
+
template<class T>
|
144
|
+
struct is_pointer_pointer<const T* const* const> : std::true_type {};
|
145
|
+
|
146
|
+
template<class T>
|
147
|
+
constexpr bool is_pointer_pointer_v = is_pointer_pointer<T>::value;
|
148
|
+
|
149
|
+
// See https://www.cppstories.com/2022/tuple-iteration-apply/
|
150
|
+
template <typename Tuple_T, typename Function_T>
|
151
|
+
void for_each_tuple(Tuple_T&& tuple, Function_T&& callable)
|
152
|
+
{
|
153
|
+
std::apply([&callable](auto&& ...args)
|
154
|
+
{
|
155
|
+
(callable(std::forward<decltype(args)>(args)), ...);
|
156
|
+
}, std::forward<Tuple_T>(tuple));
|
157
|
+
}
|
158
|
+
|
159
|
+
template<typename T, typename = void>
|
160
|
+
struct is_wrapped : std::true_type {};
|
161
|
+
|
162
|
+
template<typename T>
|
163
|
+
struct is_wrapped<T, std::enable_if_t<std::is_fundamental_v<detail::intrinsic_type<T>> ||
|
164
|
+
std::is_same_v<detail::intrinsic_type<T>, std::string>>
|
165
|
+
>: std::false_type {};
|
166
|
+
|
167
|
+
template<typename T>
|
168
|
+
constexpr bool is_wrapped_v = is_wrapped<T>::value;
|
169
|
+
} // detail
|
170
|
+
} // Rice
|
171
|
+
|
172
|
+
#endif // Rice__detail__traits__hpp_
|
data/rice.gemspec
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
2
|
+
require 'lib/rice/version'
|
3
|
+
|
4
|
+
$spec = Gem::Specification.new do |s|
|
5
|
+
s.name = 'rice'
|
6
|
+
s.version = Rice::VERSION
|
7
|
+
s.license = "MIT"
|
8
|
+
s.summary = 'Ruby Interface for C++ Extensions'
|
9
|
+
s.homepage = 'https://github.com/ruby-rice/rice'
|
10
|
+
s.authors = ['Paul Brannan', 'Jason Roelofs', 'Charlie Savage']
|
11
|
+
s.email = ['curlypaul924@gmail.com', 'jasongroelofs@gmail.com', 'cfis@savagexi.com']
|
12
|
+
|
13
|
+
s.description = <<-END
|
14
|
+
Rice is a C++ interface to Ruby's C API. It provides a type-safe and
|
15
|
+
exception-safe interface in order to make embedding Ruby and writing
|
16
|
+
Ruby extensions with C++ easier.
|
17
|
+
END
|
18
|
+
|
19
|
+
s.metadata = {
|
20
|
+
"bug_tracker_uri" => "https://github.com/ruby-rice/rice/issues",
|
21
|
+
"changelog_uri" => "https://github.com/ruby-rice/rice/blob/master/CHANGELOG.md",
|
22
|
+
"documentation_uri" => "https://ruby-rice.github.io",
|
23
|
+
"source_code_uri" => "https://github.com/ruby-rice/rice",
|
24
|
+
}
|
25
|
+
|
26
|
+
s.test_files = Dir['test/ruby/*.rb']
|
27
|
+
s.extra_rdoc_files = ['README.md']
|
28
|
+
s.require_paths = ['lib']
|
29
|
+
|
30
|
+
s.files = Dir[
|
31
|
+
# Documentation
|
32
|
+
'CHANGELOG.md',
|
33
|
+
'CONTRIBUTORS.md',
|
34
|
+
'COPYING',
|
35
|
+
'README.md',
|
36
|
+
|
37
|
+
# Ruby files
|
38
|
+
'Gemfile',
|
39
|
+
'Rakefile',
|
40
|
+
'rice.gemspec',
|
41
|
+
|
42
|
+
# CMake Files
|
43
|
+
'CMakeLists.txt',
|
44
|
+
'CMakePresets.json',
|
45
|
+
'FindRuby.cmake',
|
46
|
+
|
47
|
+
# rice.hpp
|
48
|
+
'include/rice/rice.hpp',
|
49
|
+
'include/rice/stl.hpp',
|
50
|
+
|
51
|
+
# Source files
|
52
|
+
'rice/**/*.?pp',
|
53
|
+
|
54
|
+
# Ruby files
|
55
|
+
'lib/**/*.rb',
|
56
|
+
|
57
|
+
# Samples
|
58
|
+
'sample/enum/extconf.rb',
|
59
|
+
'sample/enum/*.?pp',
|
60
|
+
'sample/enum/*.rb',
|
61
|
+
'sample/map/extconf.rb',
|
62
|
+
'sample/map/*.?pp',
|
63
|
+
'sample/map/*.rb',
|
64
|
+
'sample/inheritance/extconf.rb',
|
65
|
+
'sample/inheritance/*.?pp',
|
66
|
+
'sample/inheritance/*.rb',
|
67
|
+
'sample/callbacks/extconf.rb',
|
68
|
+
'sample/callbacks/*.?pp',
|
69
|
+
'sample/callbacks/*.rb',
|
70
|
+
|
71
|
+
# Test source files
|
72
|
+
'test/*.?pp',
|
73
|
+
'test/extconf.rb',
|
74
|
+
'test/ext/t1/extconf.rb',
|
75
|
+
'test/ext/t1/*.*pp',
|
76
|
+
'test/ext/t2/extconf.rb',
|
77
|
+
'test/ext/t2/*.*pp'
|
78
|
+
]
|
79
|
+
|
80
|
+
s.required_ruby_version = ">= 3.1"
|
81
|
+
|
82
|
+
s.add_development_dependency "bundler"
|
83
|
+
s.add_development_dependency "rake"
|
84
|
+
s.add_development_dependency "minitest"
|
85
|
+
end
|
data/test/embed_ruby.cpp
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
$: << File.join(__dir__, '..', 'ext')
|
2
|
-
|
3
|
-
require 'minitest'
|
4
|
-
require 'minitest/autorun'
|
5
|
-
|
6
|
-
class MultipleExtensionsSameClassTest < Minitest::Test
|
7
|
-
def test_multiple_extensions_same_class
|
8
|
-
require 't1/t1'
|
9
|
-
require 't2/t2'
|
10
|
-
|
11
|
-
foo = Foo.new
|
12
|
-
assert_equal 42, foo.foo
|
13
|
-
end
|
14
|
-
end
|
1
|
+
$: << File.join(__dir__, '..', 'ext')
|
2
|
+
|
3
|
+
require 'minitest'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
class MultipleExtensionsSameClassTest < Minitest::Test
|
7
|
+
def test_multiple_extensions_same_class
|
8
|
+
require 't1/t1'
|
9
|
+
require 't2/t2'
|
10
|
+
|
11
|
+
foo = Foo.new
|
12
|
+
assert_equal 42, foo.foo
|
13
|
+
end
|
14
|
+
end
|
data/test/test_Array.cpp
CHANGED
@@ -276,12 +276,15 @@ TESTCASE(assign_int)
|
|
276
276
|
* Issue 59 - Copy constructor compilation problem.
|
277
277
|
*/
|
278
278
|
|
279
|
-
namespace
|
280
|
-
|
279
|
+
namespace
|
280
|
+
{
|
281
|
+
void testArrayArg(Object self, Array string)
|
282
|
+
{
|
281
283
|
}
|
282
284
|
}
|
283
285
|
|
284
|
-
TESTCASE(use_array_in_wrapped_function)
|
286
|
+
TESTCASE(use_array_in_wrapped_function)
|
287
|
+
{
|
285
288
|
define_global_function("test_array_arg", &testArrayArg);
|
286
289
|
}
|
287
290
|
|
data/test/test_Attribute.cpp
CHANGED
@@ -31,6 +31,13 @@ namespace
|
|
31
31
|
NotAssignable& operator=(const NotAssignable&) = delete;
|
32
32
|
};
|
33
33
|
|
34
|
+
class NotCopyable
|
35
|
+
{
|
36
|
+
public:
|
37
|
+
NotCopyable() = default;
|
38
|
+
NotCopyable(const NotCopyable& other) = delete;
|
39
|
+
};
|
40
|
+
|
34
41
|
struct DataStruct
|
35
42
|
{
|
36
43
|
static inline float staticFloat = 1.0;
|
@@ -43,6 +50,7 @@ namespace
|
|
43
50
|
const int constInt = 5;
|
44
51
|
SomeClass someClass;
|
45
52
|
NotAssignable notAssignable;
|
53
|
+
NotCopyable notCopyable;
|
46
54
|
|
47
55
|
std::string inspect()
|
48
56
|
{
|
@@ -53,6 +61,21 @@ namespace
|
|
53
61
|
bool globalBool = true;
|
54
62
|
const DataStruct* globalStruct = new DataStruct();
|
55
63
|
|
64
|
+
class VecStruct
|
65
|
+
{
|
66
|
+
public:
|
67
|
+
std::vector<double> vector;
|
68
|
+
|
69
|
+
VecStruct(std::vector<double> aVector) : vector(aVector)
|
70
|
+
{
|
71
|
+
}
|
72
|
+
|
73
|
+
size_t vecSize()
|
74
|
+
{
|
75
|
+
return this->vector.size();
|
76
|
+
}
|
77
|
+
};
|
78
|
+
|
56
79
|
} // namespace
|
57
80
|
|
58
81
|
TESTCASE(attributes)
|
@@ -102,15 +125,39 @@ TESTCASE(attributes)
|
|
102
125
|
ASSERT_EQUAL("Set a string", detail::From_Ruby<std::string>().convert(result.value()));
|
103
126
|
}
|
104
127
|
|
128
|
+
TESTCASE(vector)
|
129
|
+
{
|
130
|
+
// See https ://github.com/ruby-rice/rice/issues/283
|
131
|
+
Module m = define_module("Testing");
|
132
|
+
|
133
|
+
define_class<VecStruct>("VecStruct")
|
134
|
+
.define_constructor(Constructor<VecStruct, std::vector<double>>())
|
135
|
+
.define_attr("vector", &VecStruct::vector, Rice::AttrAccess::Read)
|
136
|
+
.define_method("vector_size", &VecStruct::vecSize);
|
137
|
+
|
138
|
+
std::string code = R"(struct = VecStruct.new([1, 2])
|
139
|
+
# Access the attribute
|
140
|
+
array = struct.vector.to_a
|
141
|
+
struct.vector_size)";
|
142
|
+
|
143
|
+
Object result = m.module_eval(code);
|
144
|
+
ASSERT_EQUAL(2, detail::From_Ruby<int>().convert(result));
|
145
|
+
}
|
146
|
+
|
105
147
|
TESTCASE(const_attribute)
|
106
148
|
{
|
107
|
-
|
108
|
-
.define_constructor(Constructor<DataStruct>())
|
109
|
-
.define_attr("const_int", &DataStruct::constInt);
|
149
|
+
Data_Type<DataStruct> c = define_class<DataStruct>("DataStruct")
|
150
|
+
.define_constructor(Constructor<DataStruct>());
|
110
151
|
|
111
|
-
|
112
|
-
|
152
|
+
ASSERT_EXCEPTION_CHECK(
|
153
|
+
std::exception,
|
154
|
+
c.define_attr("const_int", &DataStruct::constInt),
|
155
|
+
ASSERT_EQUAL(ex.what(), "Cannot define attribute writer for a const attribute: const_int")
|
156
|
+
);
|
113
157
|
|
158
|
+
c.define_attr("const_int", &DataStruct::constInt, AttrAccess::Read);
|
159
|
+
Data_Object<DataStruct> o = c.call("new");
|
160
|
+
|
114
161
|
if constexpr (!oldRuby)
|
115
162
|
{
|
116
163
|
ASSERT_EXCEPTION_CHECK(
|
@@ -121,15 +168,21 @@ TESTCASE(const_attribute)
|
|
121
168
|
}
|
122
169
|
}
|
123
170
|
|
124
|
-
TESTCASE(
|
171
|
+
TESTCASE(not_assignable)
|
125
172
|
{
|
126
173
|
Class notAssignableClass = define_class<NotAssignable>("NotAssignable")
|
127
174
|
.define_constructor(Constructor<NotAssignable>());
|
128
175
|
|
129
|
-
|
130
|
-
.define_constructor(Constructor<DataStruct>())
|
131
|
-
|
176
|
+
Data_Type<DataStruct> c = define_class<DataStruct>("DataStruct")
|
177
|
+
.define_constructor(Constructor<DataStruct>());
|
178
|
+
|
179
|
+
ASSERT_EXCEPTION_CHECK(
|
180
|
+
std::exception,
|
181
|
+
c.define_attr("not_assignable", &DataStruct::notAssignable),
|
182
|
+
ASSERT_EQUAL(ex.what(), "Cannot define attribute writer for a non assignable attribute: not_assignable")
|
183
|
+
);
|
132
184
|
|
185
|
+
c.define_attr("not_assignable", &DataStruct::notAssignable, AttrAccess::Read);
|
133
186
|
Data_Object<NotAssignable> notAssignable = notAssignableClass.call("new");
|
134
187
|
|
135
188
|
Data_Object<DataStruct> o = c.call("new");
|
@@ -144,6 +197,35 @@ TESTCASE(not_copyable_attribute)
|
|
144
197
|
}
|
145
198
|
}
|
146
199
|
|
200
|
+
TESTCASE(not_copyable)
|
201
|
+
{
|
202
|
+
Class notCopyableClass = define_class<NotCopyable>("NotCopyable")
|
203
|
+
.define_constructor(Constructor<NotCopyable>());
|
204
|
+
|
205
|
+
Data_Type<DataStruct> c = define_class<DataStruct>("DataStruct")
|
206
|
+
.define_constructor(Constructor<DataStruct>());
|
207
|
+
|
208
|
+
ASSERT_EXCEPTION_CHECK(
|
209
|
+
std::exception,
|
210
|
+
c.define_attr("not_copyable", &DataStruct::notCopyable),
|
211
|
+
ASSERT_EQUAL(ex.what(), "Cannot define attribute writer for a non copy constructible attribute: not_copyable")
|
212
|
+
);
|
213
|
+
|
214
|
+
c.define_attr("not_copyable", &DataStruct::notCopyable, AttrAccess::Read);
|
215
|
+
Data_Object<NotCopyable> notCopyable = notCopyableClass.call("new");
|
216
|
+
|
217
|
+
Data_Object<DataStruct> o = c.call("new");
|
218
|
+
|
219
|
+
if constexpr (!oldRuby)
|
220
|
+
{
|
221
|
+
ASSERT_EXCEPTION_CHECK(
|
222
|
+
Exception,
|
223
|
+
o.call("not_assignable=", notCopyable),
|
224
|
+
ASSERT(std::string(ex.what()).find("undefined method `not_copyable='") == 0)
|
225
|
+
);
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
147
229
|
TESTCASE(static_attributes)
|
148
230
|
{
|
149
231
|
Class c = define_class<DataStruct>("DataStruct")
|