rice 4.3.2 → 4.5.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.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -25
  3. data/README.md +7 -2
  4. data/Rakefile +7 -1
  5. data/include/rice/rice.hpp +7321 -4470
  6. data/include/rice/stl.hpp +769 -222
  7. data/lib/mkmf-rice.rb +37 -95
  8. data/rice/Address_Registration_Guard.hpp +72 -3
  9. data/rice/Arg.hpp +19 -5
  10. data/rice/Arg.ipp +24 -0
  11. data/rice/Callback.hpp +21 -0
  12. data/rice/Callback.ipp +13 -0
  13. data/rice/Constructor.hpp +4 -27
  14. data/rice/Constructor.ipp +79 -0
  15. data/rice/Data_Object.hpp +74 -3
  16. data/rice/Data_Object.ipp +324 -32
  17. data/rice/Data_Type.hpp +215 -3
  18. data/rice/Data_Type.ipp +125 -64
  19. data/rice/Director.hpp +0 -2
  20. data/rice/Enum.hpp +4 -6
  21. data/rice/Enum.ipp +101 -57
  22. data/rice/Exception.hpp +62 -2
  23. data/rice/Exception.ipp +7 -12
  24. data/rice/JumpException.hpp +44 -0
  25. data/rice/JumpException.ipp +48 -0
  26. data/rice/MemoryView.hpp +11 -0
  27. data/rice/MemoryView.ipp +43 -0
  28. data/rice/Return.hpp +6 -26
  29. data/rice/Return.ipp +10 -16
  30. data/rice/detail/DefaultHandler.hpp +12 -0
  31. data/rice/detail/DefaultHandler.ipp +8 -0
  32. data/rice/detail/HandlerRegistry.hpp +5 -35
  33. data/rice/detail/HandlerRegistry.ipp +7 -11
  34. data/rice/detail/InstanceRegistry.hpp +1 -4
  35. data/rice/detail/MethodInfo.hpp +15 -5
  36. data/rice/detail/MethodInfo.ipp +78 -6
  37. data/rice/detail/Native.hpp +32 -0
  38. data/rice/detail/Native.ipp +129 -0
  39. data/rice/detail/NativeAttributeGet.hpp +51 -0
  40. data/rice/detail/NativeAttributeGet.ipp +51 -0
  41. data/rice/detail/NativeAttributeSet.hpp +43 -0
  42. data/rice/detail/NativeAttributeSet.ipp +82 -0
  43. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  44. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  45. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  46. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  47. data/rice/detail/NativeFunction.hpp +20 -21
  48. data/rice/detail/NativeFunction.ipp +199 -64
  49. data/rice/detail/NativeIterator.hpp +8 -11
  50. data/rice/detail/NativeIterator.ipp +27 -31
  51. data/rice/detail/NativeRegistry.hpp +24 -17
  52. data/rice/detail/NativeRegistry.ipp +23 -56
  53. data/rice/detail/Proc.hpp +4 -0
  54. data/rice/detail/Proc.ipp +85 -0
  55. data/rice/detail/Registries.hpp +0 -7
  56. data/rice/detail/Registries.ipp +0 -18
  57. data/rice/detail/RubyFunction.hpp +0 -3
  58. data/rice/detail/RubyFunction.ipp +4 -8
  59. data/rice/detail/RubyType.hpp +19 -0
  60. data/rice/detail/RubyType.ipp +187 -0
  61. data/rice/detail/TupleIterator.hpp +14 -0
  62. data/rice/detail/Type.hpp +5 -6
  63. data/rice/detail/Type.ipp +150 -33
  64. data/rice/detail/TypeRegistry.hpp +15 -7
  65. data/rice/detail/TypeRegistry.ipp +105 -12
  66. data/rice/detail/Wrapper.hpp +6 -5
  67. data/rice/detail/Wrapper.ipp +45 -23
  68. data/rice/detail/cpp_protect.hpp +5 -6
  69. data/rice/detail/default_allocation_func.ipp +0 -2
  70. data/rice/detail/from_ruby.hpp +37 -3
  71. data/rice/detail/from_ruby.ipp +911 -454
  72. data/rice/detail/ruby.hpp +18 -0
  73. data/rice/detail/to_ruby.hpp +41 -3
  74. data/rice/detail/to_ruby.ipp +437 -113
  75. data/rice/global_function.hpp +0 -4
  76. data/rice/global_function.ipp +1 -2
  77. data/rice/rice.hpp +105 -22
  78. data/rice/ruby_mark.hpp +4 -3
  79. data/rice/stl.hpp +4 -0
  80. data/test/embed_ruby.cpp +4 -1
  81. data/test/extconf.rb +2 -0
  82. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  83. data/test/test_Address_Registration_Guard.cpp +5 -0
  84. data/test/test_Array.cpp +12 -1
  85. data/test/test_Attribute.cpp +103 -21
  86. data/test/test_Builtin_Object.cpp +5 -0
  87. data/test/test_Callback.cpp +231 -0
  88. data/test/test_Class.cpp +5 -31
  89. data/test/test_Constructor.cpp +69 -6
  90. data/test/test_Data_Object.cpp +9 -4
  91. data/test/test_Data_Type.cpp +428 -64
  92. data/test/test_Director.cpp +10 -5
  93. data/test/test_Enum.cpp +152 -40
  94. data/test/test_Exception.cpp +235 -0
  95. data/test/test_File.cpp +70 -0
  96. data/test/test_From_Ruby.cpp +542 -0
  97. data/test/test_Hash.cpp +5 -0
  98. data/test/test_Identifier.cpp +5 -0
  99. data/test/test_Inheritance.cpp +6 -1
  100. data/test/test_Iterator.cpp +5 -0
  101. data/test/test_JumpException.cpp +22 -0
  102. data/test/test_Keep_Alive.cpp +6 -1
  103. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -0
  104. data/test/test_Memory_Management.cpp +5 -0
  105. data/test/test_Module.cpp +118 -64
  106. data/test/test_Native_Registry.cpp +2 -33
  107. data/test/test_Object.cpp +5 -0
  108. data/test/test_Overloads.cpp +631 -0
  109. data/test/test_Ownership.cpp +67 -4
  110. data/test/test_Proc.cpp +45 -0
  111. data/test/test_Self.cpp +5 -0
  112. data/test/test_Stl_Exception.cpp +109 -0
  113. data/test/test_Stl_Map.cpp +22 -8
  114. data/test/test_Stl_Optional.cpp +5 -0
  115. data/test/test_Stl_Pair.cpp +7 -2
  116. data/test/test_Stl_Reference_Wrapper.cpp +5 -0
  117. data/test/test_Stl_SmartPointer.cpp +210 -5
  118. data/test/test_Stl_String.cpp +5 -0
  119. data/test/test_Stl_String_View.cpp +5 -0
  120. data/test/test_Stl_Type.cpp +147 -0
  121. data/test/test_Stl_Unordered_Map.cpp +18 -7
  122. data/test/test_Stl_Variant.cpp +5 -0
  123. data/test/test_Stl_Vector.cpp +130 -8
  124. data/test/test_String.cpp +5 -0
  125. data/test/test_Struct.cpp +5 -0
  126. data/test/test_Symbol.cpp +5 -0
  127. data/test/test_Template.cpp +192 -0
  128. data/test/test_To_Ruby.cpp +152 -0
  129. data/test/test_Tracking.cpp +1 -0
  130. data/test/test_Type.cpp +100 -0
  131. data/test/test_global_functions.cpp +53 -6
  132. data/test/unittest.cpp +8 -0
  133. metadata +37 -20
  134. data/lib/version.rb +0 -3
  135. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  136. data/rice/Data_Object_defn.hpp +0 -84
  137. data/rice/Data_Type_defn.hpp +0 -190
  138. data/rice/Exception_defn.hpp +0 -68
  139. data/rice/HandlerRegistration.hpp +0 -15
  140. data/rice/Identifier.hpp +0 -50
  141. data/rice/Identifier.ipp +0 -29
  142. data/rice/detail/ExceptionHandler.hpp +0 -8
  143. data/rice/detail/ExceptionHandler.ipp +0 -28
  144. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  145. data/rice/detail/Jump_Tag.hpp +0 -21
  146. data/rice/detail/NativeAttribute.hpp +0 -64
  147. data/rice/detail/NativeAttribute.ipp +0 -112
  148. data/rice/detail/from_ruby_defn.hpp +0 -38
  149. data/rice/detail/to_ruby_defn.hpp +0 -48
  150. data/test/test_Jump_Tag.cpp +0 -17
  151. data/test/test_To_From_Ruby.cpp +0 -399
@@ -1,82 +1,49 @@
1
1
 
2
- // Ruby 2.7 now includes a similarly named macro that uses templates to
3
- // pick the right overload for the underlying function. That doesn't work
4
- // for our cases because we are using this method dynamically and get a
5
- // compilation error otherwise. This removes the macro and lets us fall
6
- // back to the C-API underneath again.
7
- #undef rb_define_method_id
8
-
9
- #include "RubyFunction.hpp"
10
-
11
2
  namespace Rice::detail
12
3
  {
13
- // Effective Java (2nd edition)
14
- // https://stackoverflow.com/a/2634715
15
- inline size_t NativeRegistry::key(VALUE klass, ID id)
16
- {
17
- uint32_t prime = 53;
18
- return (prime + klass) * prime + id;
19
- }
20
-
21
- inline void NativeRegistry::add(VALUE klass, ID method_id, std::any callable)
4
+ inline void NativeRegistry::add(VALUE klass, ID methodId, std::unique_ptr<Native>& native)
22
5
  {
23
6
  if (rb_type(klass) == T_ICLASS)
24
7
  {
25
8
  klass = detail::protect(rb_class_of, klass);
26
9
  }
27
10
 
28
- auto range = this->natives_.equal_range(key(klass, method_id));
29
- for (auto it = range.first; it != range.second; ++it)
30
- {
31
- const auto [k, m, d] = it->second;
11
+ // Create the key
12
+ std::pair<VALUE, ID> key = std::make_pair(klass, methodId);
32
13
 
33
- if (k == klass && m == method_id)
34
- {
35
- std::get<2>(it->second) = callable;
36
- return;
37
- }
38
- }
14
+ // Lookup items for method
15
+ std::vector<std::unique_ptr<Native>>& natives = this->natives_[key];
39
16
 
40
- this->natives_.emplace(std::make_pair(key(klass, method_id), std::make_tuple(klass, method_id, callable)));
17
+ natives.push_back(std::move(native));
41
18
  }
42
19
 
43
- template <typename Return_T>
44
- inline Return_T NativeRegistry::lookup()
20
+ inline void NativeRegistry::reset(VALUE klass)
45
21
  {
46
- ID method_id;
47
- VALUE klass;
48
- if (!rb_frame_method_id_and_class(&method_id, &klass))
22
+ for (auto iter = this->natives_.begin(); iter != this->natives_.end();)
49
23
  {
50
- rb_raise(rb_eRuntimeError, "Cannot get method id and class for function");
24
+ // Iter points to a std::pair<std::pair<VALUE, ID>, std::vector<NativeRegistryItem>
25
+ if (iter->first.first == klass)
26
+ {
27
+ iter = this->natives_.erase(iter);
28
+ }
29
+ else
30
+ {
31
+ ++iter;
32
+ }
51
33
  }
52
-
53
- return this->lookup<Return_T>(klass, method_id);
54
34
  }
55
-
56
- template <typename Return_T>
57
- inline Return_T NativeRegistry::lookup(VALUE klass, ID method_id)
35
+
36
+ inline const std::vector<std::unique_ptr<Native>>& NativeRegistry::lookup(VALUE klass, ID methodId)
58
37
  {
59
38
  if (rb_type(klass) == T_ICLASS)
60
39
  {
61
40
  klass = detail::protect(rb_class_of, klass);
62
41
  }
63
42
 
64
- auto range = this->natives_.equal_range(key(klass, method_id));
65
- for (auto it = range.first; it != range.second; ++it)
66
- {
67
- const auto [k, m, d] = it->second;
68
-
69
- if (k == klass && m == method_id)
70
- {
71
- auto* ptr = std::any_cast<Return_T>(&d);
72
- if (!ptr)
73
- {
74
- rb_raise(rb_eRuntimeError, "Unexpected return type for %s#%s", rb_class2name(klass), rb_id2name(method_id));
75
- }
76
- return *ptr;
77
- }
78
- }
43
+ // Create the key
44
+ std::pair<VALUE, ID> key = std::make_pair(klass, methodId);
79
45
 
80
- rb_raise(rb_eRuntimeError, "Could not find data for klass and method id");
46
+ // Lookup items for method
47
+ return this->natives_[key];
81
48
  }
82
49
  }
@@ -0,0 +1,4 @@
1
+ #ifndef Rice__Proc__hpp_
2
+ #define Rice__Proc__hpp_
3
+
4
+ #endif // Rice__Proc__hpp_
@@ -0,0 +1,85 @@
1
+ namespace Rice::detail
2
+ {
3
+ // Note Return_T(Arg_Ts...) is intentional versus Return_T(*)(Arg_Ts...). That is
4
+ // because the Type machinery strips all pointers/references/const/val etc to avoid
5
+ // having an explosion of Type definitions
6
+ template<typename Return_T, typename ...Arg_Ts>
7
+ struct Type<Return_T(Arg_Ts...)>
8
+ {
9
+ static bool verify()
10
+ {
11
+ return true;
12
+ }
13
+ };
14
+
15
+ // Wraps a C++ function as a Ruby proc
16
+ template<typename Return_T, typename ...Arg_Ts>
17
+ class To_Ruby<Return_T(*)(Arg_Ts...)>
18
+ {
19
+ public:
20
+ using Proc_T = Return_T(*)(Arg_Ts...);
21
+
22
+ VALUE convert(Proc_T proc)
23
+ {
24
+ using NativeFunction_T = NativeFunction<void, Proc_T, false>;
25
+ auto native = new NativeFunction_T(proc);
26
+ VALUE result = rb_proc_new(NativeFunction_T::procEntry, (VALUE)native);
27
+
28
+ // Tie the lifetime of the NativeCallback C++ instance to the lifetime of the Ruby proc object
29
+ VALUE finalizer = rb_proc_new(NativeFunction_T::finalizerCallback, (VALUE)native);
30
+ rb_define_finalizer(result, finalizer);
31
+
32
+ return result;
33
+ }
34
+ };
35
+
36
+ // Makes a Ruby proc callable as C callback
37
+ template<typename Return_T, typename ...Arg_Ts>
38
+ class From_Ruby<Return_T(*)(Arg_Ts...)>
39
+ {
40
+ public:
41
+ using Callback_T = Return_T(*)(Arg_Ts...);
42
+
43
+ From_Ruby() = default;
44
+
45
+ explicit From_Ruby(Arg* arg) : arg_(arg)
46
+ {
47
+ }
48
+
49
+ Convertible is_convertible(VALUE value)
50
+ {
51
+ if (protect(rb_obj_is_proc, value) == Qtrue || protect(rb_proc_lambda_p, value))
52
+ {
53
+ return Convertible::Exact;
54
+ }
55
+ else
56
+ {
57
+ return Convertible::None;
58
+ }
59
+ }
60
+
61
+ #ifdef HAVE_LIBFFI
62
+ Callback_T convert(VALUE value)
63
+ {
64
+ using NativeCallback_T = NativeCallbackFFI<Return_T(*)(Arg_Ts...)>;
65
+ NativeCallback_T* nativeCallback = new NativeCallback_T(value);
66
+
67
+ // Tie the lifetime of the NativeCallback C++ instance to the lifetime of the Ruby proc object
68
+ VALUE finalizer = rb_proc_new(NativeCallback_T::finalizerCallback, (VALUE)nativeCallback);
69
+ rb_define_finalizer(value, finalizer);
70
+
71
+ return nativeCallback->callback();
72
+ }
73
+ #else
74
+ Callback_T convert(VALUE value)
75
+ {
76
+ using NativeCallback_T = NativeCallbackSimple<Return_T(*)(Arg_Ts...)>;
77
+ NativeCallback_T::proc = value;
78
+ return &NativeCallback_T::callback;
79
+ }
80
+ #endif
81
+
82
+ private:
83
+ Arg* arg_ = nullptr;
84
+ };
85
+ }
@@ -1,11 +1,6 @@
1
1
  #ifndef Rice__Registries__hpp_
2
2
  #define Rice__Registries__hpp_
3
3
 
4
- #include "HandlerRegistry.hpp"
5
- #include "InstanceRegistry.hpp"
6
- #include "NativeRegistry.hpp"
7
- #include "TypeRegistry.hpp"
8
-
9
4
  namespace Rice::detail
10
5
  {
11
6
  class Registries
@@ -21,6 +16,4 @@ namespace Rice::detail
21
16
  };
22
17
  }
23
18
 
24
- #include "Registries.ipp"
25
-
26
19
  #endif // Rice__Registries__hpp_
@@ -2,22 +2,4 @@ namespace Rice::detail
2
2
  {
3
3
  //Initialize static variables here.
4
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
5
  }
@@ -1,8 +1,6 @@
1
1
  #ifndef Rice__detail__ruby_function__hpp_
2
2
  #define Rice__detail__ruby_function__hpp_
3
3
 
4
- #include "ruby.hpp"
5
-
6
4
  namespace Rice::detail
7
5
  {
8
6
  /* This is functor class that wraps calls to a Ruby C API method. It is needed because
@@ -29,6 +27,5 @@ namespace Rice::detail
29
27
  template<typename Function_T, typename ...Arg_Ts>
30
28
  auto protect(Function_T func, Arg_Ts...args);
31
29
  }
32
- #include "RubyFunction.ipp"
33
30
 
34
31
  #endif // Rice__detail__ruby_function__hpp_
@@ -1,5 +1,3 @@
1
- #include "Jump_Tag.hpp"
2
- #include "../Exception_defn.hpp"
3
1
 
4
2
  #include <any>
5
3
 
@@ -14,9 +12,6 @@ namespace Rice::detail
14
12
  template<typename Function_T, typename...Arg_Ts>
15
13
  inline typename RubyFunction<Function_T, Arg_Ts...>::Return_T RubyFunction<Function_T, Arg_Ts...>::operator()()
16
14
  {
17
- const int TAG_RAISE = 0x6; // From Ruby header files
18
- int state = 0;
19
-
20
15
  // Setup a thread local variable to capture the result of the Ruby function call.
21
16
  // We use thread_local because the lambda has to be captureless so it can
22
17
  // be converted to a function pointer callable by C.
@@ -45,10 +40,11 @@ namespace Rice::detail
45
40
  };
46
41
 
47
42
  // Now call rb_protect which will invoke the callback lambda above
43
+ int state = (int)JumpException::RUBY_TAG_NONE;
48
44
  rb_protect(callback, (VALUE)this, &state);
49
45
 
50
46
  // Did anything go wrong?
51
- if (state == 0)
47
+ if (state == JumpException::RUBY_TAG_NONE)
52
48
  {
53
49
  if constexpr (!std::is_same_v<Return_T, void>)
54
50
  {
@@ -58,14 +54,14 @@ namespace Rice::detail
58
54
  else
59
55
  {
60
56
  VALUE err = rb_errinfo();
61
- if (state == TAG_RAISE && RB_TEST(err))
57
+ if (state == JumpException::RUBY_TAG_RAISE && RB_TEST(err))
62
58
  {
63
59
  rb_set_errinfo(Qnil);
64
60
  throw Rice::Exception(err);
65
61
  }
66
62
  else
67
63
  {
68
- throw Jump_Tag(state);
64
+ throw Rice::JumpException((Rice::JumpException::ruby_tag_type)state);
69
65
  }
70
66
  }
71
67
  }
@@ -0,0 +1,19 @@
1
+ #ifndef Rice__detail__ruby__type__hpp_
2
+ #define Rice__detail__ruby__type__hpp_
3
+
4
+ #include <set>
5
+
6
+ namespace Rice::detail
7
+ {
8
+ template <typename T>
9
+ class RubyType
10
+ {
11
+ public:
12
+ static std::set<ruby_value_type> types();
13
+ static std::set<ruby_value_type> convertibleFrom();
14
+ static T(*converter)(VALUE);
15
+ static std::string packTemplate;
16
+ };
17
+ }
18
+
19
+ #endif // Rice__detail__ruby__type__hpp_
@@ -0,0 +1,187 @@
1
+ namespace Rice::detail
2
+ {
3
+ template<>
4
+ class RubyType<bool>
5
+ {
6
+ public:
7
+ using FromRuby_T = bool(*)(VALUE);
8
+
9
+ static inline FromRuby_T fromRuby = RB_TEST;
10
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_TRUE, RUBY_T_FALSE };
11
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_NIL };
12
+ static inline std::set<ruby_value_type> Narrowable = { };
13
+ static inline std::string packTemplate = "not supported";
14
+ };
15
+
16
+ template<>
17
+ class RubyType<char>
18
+ {
19
+ public:
20
+ using FromRuby_T = char(*)(VALUE);
21
+
22
+ static inline FromRuby_T fromRuby = rb_num2char_inline;
23
+ static inline std::set<ruby_value_type> Exact = { };
24
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
25
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
26
+ static inline std::string packTemplate = CHAR_MIN < 0 ? "c*" : "C*";
27
+ };
28
+
29
+ template<>
30
+ class RubyType<signed char>
31
+ {
32
+ public:
33
+ // Hack - need to later typecast
34
+ using FromRuby_T = char(*)(VALUE);
35
+
36
+ static inline FromRuby_T fromRuby = rb_num2char_inline;
37
+ static inline std::set<ruby_value_type> Exact = { };
38
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
39
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
40
+ static inline std::string packTemplate = "c*";
41
+ };
42
+
43
+ template<>
44
+ class RubyType<unsigned char>
45
+ {
46
+ public:
47
+ // Hack - need to later typecast, although char's in ruby are unsigned
48
+ using FromRuby_T = char(*)(VALUE);
49
+
50
+ static inline FromRuby_T fromRuby = rb_num2char_inline;
51
+ static inline std::set<ruby_value_type> Exact = { };
52
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
53
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
54
+ static inline std::string packTemplate = "C*";
55
+ };
56
+
57
+ template<>
58
+ class RubyType<short>
59
+ {
60
+ public:
61
+ using FromRuby_T = short(*)(VALUE);
62
+
63
+ static inline FromRuby_T fromRuby = rb_num2short_inline;
64
+ static inline std::set<ruby_value_type> Exact = { };
65
+ static inline std::set<ruby_value_type> Castable = { };
66
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
67
+ static inline std::string packTemplate = "s*";
68
+ };
69
+
70
+ template<>
71
+ class RubyType<unsigned short>
72
+ {
73
+ public:
74
+ using FromRuby_T = unsigned short(*)(VALUE);
75
+
76
+ static inline FromRuby_T fromRuby = rb_num2ushort;
77
+ static inline std::set<ruby_value_type> Exact = { };
78
+ static inline std::set<ruby_value_type> Castable = { };
79
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
80
+ static inline std::string packTemplate = "S*";
81
+ };
82
+
83
+ template<>
84
+ class RubyType<int>
85
+ {
86
+ public:
87
+ using FromRuby_T = int(*)(VALUE);
88
+
89
+ static inline FromRuby_T fromRuby = rb_num2int_inline;
90
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
91
+ static inline std::set<ruby_value_type> Castable = { };
92
+ static inline std::set<ruby_value_type> Narrowable = { };
93
+ static inline std::string packTemplate = "i*";
94
+ };
95
+
96
+ template<>
97
+ class RubyType<unsigned int>
98
+ {
99
+ public:
100
+ using FromRuby_T = unsigned int(*)(VALUE);
101
+
102
+ static inline FromRuby_T fromRuby = RB_NUM2UINT;
103
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
104
+ static inline std::set<ruby_value_type> Castable = { };
105
+ static inline std::set<ruby_value_type> Narrowable = { };
106
+ static inline std::string packTemplate = "I*";
107
+ };
108
+
109
+ template<>
110
+ class RubyType<long>
111
+ {
112
+ public:
113
+ using FromRuby_T = long(*)(VALUE);
114
+
115
+ static inline FromRuby_T fromRuby = rb_num2long_inline;
116
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
117
+ static inline std::set<ruby_value_type> Castable = { };
118
+ static inline std::set<ruby_value_type> Narrowable = { };
119
+ static inline std::string packTemplate = "l_*";
120
+ };
121
+
122
+ template<>
123
+ class RubyType<unsigned long>
124
+ {
125
+ public:
126
+ using FromRuby_T = unsigned long(*)(VALUE);
127
+
128
+ static inline FromRuby_T fromRuby = rb_num2ulong_inline;
129
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
130
+ static inline std::set<ruby_value_type> Castable = { };
131
+ static inline std::set<ruby_value_type> Narrowable = { };
132
+ static inline std::string packTemplate = "L_*";
133
+ };
134
+
135
+ template<>
136
+ class RubyType<long long>
137
+ {
138
+ public:
139
+ using FromRuby_T = long long(*)(VALUE);
140
+
141
+ static inline FromRuby_T fromRuby = rb_num2ll_inline;
142
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM, RUBY_T_BIGNUM };
143
+ static inline std::set<ruby_value_type> Castable = { };
144
+ static inline std::set<ruby_value_type> Narrowable = { };
145
+ static inline std::string packTemplate = "q_*";
146
+ };
147
+
148
+ template<>
149
+ class RubyType<unsigned long long>
150
+ {
151
+ public:
152
+ using FromRuby_T = unsigned long long(*)(VALUE);
153
+
154
+ static inline FromRuby_T fromRuby = RB_NUM2ULL;
155
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM, RUBY_T_BIGNUM };
156
+ static inline std::set<ruby_value_type> Castable = { };
157
+ static inline std::set<ruby_value_type> Narrowable = { };
158
+ static inline std::string packTemplate = "Q_*";
159
+ };
160
+
161
+
162
+ template<>
163
+ class RubyType<float>
164
+ {
165
+ public:
166
+ using FromRuby_T = double(*)(VALUE);
167
+
168
+ static inline FromRuby_T fromRuby = rb_num2dbl;
169
+ static inline std::set<ruby_value_type> Exact = { };
170
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_FIXNUM };
171
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FLOAT };
172
+ static inline std::string packTemplate = "f*";
173
+ };
174
+
175
+ template<>
176
+ class RubyType<double>
177
+ {
178
+ public:
179
+ using FromRuby_T = double(*)(VALUE);
180
+
181
+ static inline FromRuby_T fromRuby = rb_num2dbl;
182
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FLOAT };
183
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_FIXNUM, RUBY_T_BIGNUM };
184
+ static inline std::set<ruby_value_type> Narrowable = { };
185
+ static inline std::string packTemplate = "d*";
186
+ };
187
+ }
@@ -0,0 +1,14 @@
1
+ #ifndef Rice__stl__tuple_iterator__hpp_
2
+ #define Rice__stl__tuple_iterator__hpp_
3
+
4
+ // See https://www.cppstories.com/2022/tuple-iteration-apply/
5
+ template <typename Tuple_T, typename Function_T>
6
+ void for_each_tuple(Tuple_T&& tuple, Function_T&& callable)
7
+ {
8
+ std::apply([&callable](auto&& ...args)
9
+ {
10
+ (callable(std::forward<decltype(args)>(args)), ...);
11
+ }, std::forward<Tuple_T>(tuple));
12
+ }
13
+
14
+ #endif // Rice__stl__tuple_iterator__hpp_
data/rice/detail/Type.hpp CHANGED
@@ -1,9 +1,7 @@
1
1
  #ifndef Rice__Type__hpp_
2
2
  #define Rice__Type__hpp_
3
3
 
4
- #include <string>
5
- #include <typeinfo>
6
- #include "../traits/rice_traits.hpp"
4
+ #include <regex>
7
5
 
8
6
  namespace Rice::detail
9
7
  {
@@ -15,7 +13,10 @@ namespace Rice::detail
15
13
 
16
14
  // Return the name of a type
17
15
  std::string typeName(const std::type_info& typeInfo);
18
- std::string makeClassName(const std::type_info& typeInfo);
16
+ std::string typeName(const std::type_index& typeIndex);
17
+ std::string makeClassName(const std::string& typeInfoName);
18
+ std::string findGroup(std::string& string, size_t start = 0);
19
+ void replaceAll(std::string& string, std::regex regex, std::string replacement);
19
20
 
20
21
  template<typename T>
21
22
  void verifyType();
@@ -24,6 +25,4 @@ namespace Rice::detail
24
25
  void verifyTypes();
25
26
  }
26
27
 
27
- #include "Type.ipp"
28
-
29
28
  #endif // Rice__Type__hpp_