rice 4.11.0 → 4.11.2

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.
@@ -8,16 +8,9 @@ namespace Rice
8
8
  {
9
9
  }
10
10
 
11
- inline Object::operator bool() const
12
- {
13
- // Bypass getter to not raise exception
14
- return RTEST(this->value_.value());
15
- }
16
-
17
- inline bool Object::is_nil() const
11
+ inline VALUE Object::value() const
18
12
  {
19
- // Bypass getter to not raise exception
20
- return NIL_P(this->value_.value());
13
+ return this->value_.value();
21
14
  }
22
15
 
23
16
  inline Object::operator VALUE() const
@@ -25,9 +18,9 @@ namespace Rice
25
18
  return this->value();
26
19
  }
27
20
 
28
- inline VALUE Object::value() const
21
+ inline VALUE Object::validated_value() const
29
22
  {
30
- VALUE result = this->value_.value();
23
+ VALUE result = this->value();
31
24
 
32
25
  if (result == Qnil)
33
26
  {
@@ -38,6 +31,16 @@ namespace Rice
38
31
  return result;
39
32
  }
40
33
 
34
+ inline Object::operator bool() const
35
+ {
36
+ return RTEST(this->value());
37
+ }
38
+
39
+ inline bool Object::is_nil() const
40
+ {
41
+ return NIL_P(this->value());
42
+ }
43
+
41
44
  template<typename ...Parameter_Ts>
42
45
  inline Object Object::call(Identifier id, Parameter_Ts... args) const
43
46
  {
@@ -49,7 +52,7 @@ namespace Rice
49
52
  easy to duplicate by setting GC.stress to true and calling a constructor
50
53
  that takes multiple values like a std::pair wrapper. */
51
54
  std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(std::forward<Parameter_Ts>(args))... };
52
- return detail::protect(rb_funcallv, value(), id.id(), (int)values.size(), (const VALUE*)values.data());
55
+ return detail::protect(rb_funcallv, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data());
53
56
  }
54
57
 
55
58
  template<typename ...Parameter_Ts>
@@ -57,13 +60,13 @@ namespace Rice
57
60
  {
58
61
  /* IMPORTANT - See call() above */
59
62
  std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(args)... };
60
- return detail::protect(rb_funcallv_kw, value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
63
+ return detail::protect(rb_funcallv_kw, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
61
64
  }
62
65
 
63
66
  template<typename T>
64
67
  inline void Object::iv_set(Identifier name, T const& value)
65
68
  {
66
- detail::protect(rb_ivar_set, this->value(), name.id(), detail::To_Ruby<T>().convert(value));
69
+ detail::protect(rb_ivar_set, this->validated_value(), name.id(), detail::To_Ruby<T>().convert(value));
67
70
  }
68
71
 
69
72
  inline int Object::compare(Object const& other) const
@@ -79,66 +82,71 @@ namespace Rice
79
82
  return this->is_nil() && other.is_nil();
80
83
  }
81
84
 
82
- VALUE result = detail::protect(rb_equal, this->value(), other.value());
85
+ VALUE result = detail::protect(rb_equal, this->validated_value(), other.validated_value());
83
86
  return RB_TEST(result);
84
87
  }
85
88
 
86
89
  inline bool Object::is_eql(const Object& other) const
87
90
  {
88
- VALUE result = detail::protect(rb_eql, this->value(), other.value());
91
+ if (this->is_nil() || other.is_nil())
92
+ {
93
+ return this->is_nil() && other.is_nil();
94
+ }
95
+
96
+ VALUE result = detail::protect(rb_eql, this->validated_value(), other.validated_value());
89
97
  return RB_TEST(result);
90
98
  }
91
99
 
92
100
  inline void Object::freeze()
93
101
  {
94
- detail::protect(rb_obj_freeze, value());
102
+ detail::protect(rb_obj_freeze, this->validated_value());
95
103
  }
96
104
 
97
105
  inline bool Object::is_frozen() const
98
106
  {
99
- return RB_OBJ_FROZEN(value());
107
+ return RB_OBJ_FROZEN(this->validated_value());
100
108
  }
101
109
 
102
110
  inline int Object::rb_type() const
103
111
  {
104
- return ::rb_type(this->value());
112
+ return ::rb_type(this->validated_value());
105
113
  }
106
114
 
107
115
  inline VALUE Object::object_id() const
108
116
  {
109
- return detail::protect(rb_obj_id, this->value());
117
+ return detail::protect(rb_obj_id, this->validated_value());
110
118
  }
111
119
 
112
120
  inline bool Object::is_a(Object klass) const
113
121
  {
114
- VALUE result = detail::protect(rb_obj_is_kind_of, this->value(), klass.value());
122
+ VALUE result = detail::protect(rb_obj_is_kind_of, this->validated_value(), klass.validated_value());
115
123
  return RB_TEST(result);
116
124
  }
117
125
 
118
126
  inline void Object::extend(Module const& mod)
119
127
  {
120
- detail::protect(rb_extend_object, this->value(), mod.value());
128
+ detail::protect(rb_extend_object, this->validated_value(), mod.validated_value());
121
129
  }
122
130
 
123
131
  inline bool Object::respond_to(Identifier id) const
124
132
  {
125
- return bool(rb_respond_to(this->value(), id.id()));
133
+ return bool(rb_respond_to(this->validated_value(), id.id()));
126
134
  }
127
135
 
128
136
  inline bool Object::is_instance_of(Object klass) const
129
137
  {
130
- VALUE result = detail::protect(rb_obj_is_instance_of, this->value(), klass.value());
138
+ VALUE result = detail::protect(rb_obj_is_instance_of, this->validated_value(), klass.validated_value());
131
139
  return RB_TEST(result);
132
140
  }
133
141
 
134
142
  inline Object Object::iv_get(Identifier name) const
135
143
  {
136
- return detail::protect(rb_ivar_get, this->value(), name.id());
144
+ return detail::protect(rb_ivar_get, this->validated_value(), name.id());
137
145
  }
138
146
 
139
147
  inline Object Object::attr_get(Identifier name) const
140
148
  {
141
- return detail::protect(rb_attr_get, this->value(), name.id());
149
+ return detail::protect(rb_attr_get, this->validated_value(), name.id());
142
150
  }
143
151
 
144
152
  inline void Object::set_value(VALUE value)
@@ -148,20 +156,20 @@ namespace Rice
148
156
 
149
157
  inline Object Object::const_get(Identifier name) const
150
158
  {
151
- return detail::protect(rb_const_get, this->value(), name.id());
159
+ return detail::protect(rb_const_get, this->validated_value(), name.id());
152
160
  }
153
161
 
154
162
  inline bool Object::const_defined(Identifier name) const
155
163
  {
156
- size_t result = detail::protect(rb_const_defined, this->value(), name.id());
164
+ size_t result = detail::protect(rb_const_defined, this->validated_value(), name.id());
157
165
  return bool(result);
158
166
  }
159
167
 
160
168
  inline Object Object::const_set(Identifier name, Object value)
161
169
  {
162
170
  // We will allow setting constants to Qnil, or the decimal value of 4. This happens
163
- // in C++ libraries with enums. Thus skip the value() method that raises excptions
164
- detail::protect(rb_const_set, this->value(), name.id(), value.value_.value());
171
+ // in C++ libraries with enums. Thus use value() instead of validated_value
172
+ detail::protect(rb_const_set, this->validated_value(), name.id(), value.value());
165
173
  return value;
166
174
  }
167
175
 
@@ -176,7 +184,7 @@ namespace Rice
176
184
 
177
185
  inline void Object::remove_const(Identifier name)
178
186
  {
179
- detail::protect(rb_mod_remove_const, this->value(), name.to_sym());
187
+ detail::protect(rb_mod_remove_const, this->validated_value(), name.to_sym());
180
188
  }
181
189
 
182
190
  inline bool operator==(Object const& lhs, Object const& rhs)
@@ -47,22 +47,22 @@ namespace Rice
47
47
 
48
48
  inline size_t String::length() const
49
49
  {
50
- return RSTRING_LEN(value());
50
+ return RSTRING_LEN(this->value());
51
51
  }
52
52
 
53
53
  inline char String::operator[](ptrdiff_t index) const
54
54
  {
55
- return RSTRING_PTR(value())[index];
55
+ return RSTRING_PTR(this->value())[index];
56
56
  }
57
57
 
58
58
  inline char const* String::c_str() const
59
59
  {
60
- return RSTRING_PTR(value());
60
+ return RSTRING_PTR(this->value());
61
61
  }
62
62
 
63
63
  inline std::string String::str() const
64
64
  {
65
- return std::string(RSTRING_PTR(value()), length());
65
+ return std::string(RSTRING_PTR(this->value()), length());
66
66
  }
67
67
 
68
68
  template<typename T>
@@ -9,7 +9,7 @@
9
9
  */
10
10
  inline auto& include_module(Module const& inc)
11
11
  {
12
- detail::protect(rb_include_module, this->value(), inc.value());
12
+ detail::protect(rb_include_module, this->validated_value(), inc.value());
13
13
  return *this;
14
14
  }
15
15
 
@@ -33,7 +33,7 @@ inline auto& include_module(Module const& inc)
33
33
  template<typename Method_T, typename...Arg_Ts>
34
34
  inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
35
35
  {
36
- this->wrap_native_method(this->value(), name, std::forward<Method_T>(method), args...);
36
+ this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
37
37
  return *this;
38
38
  }
39
39
 
@@ -51,7 +51,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
51
51
  template<typename Function_T, typename...Arg_Ts>
52
52
  inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
53
53
  {
54
- this->wrap_native_function(this->value(), name, std::forward<Function_T>(func), args...);
54
+ this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
55
55
  return *this;
56
56
  }
57
57
 
@@ -125,6 +125,6 @@ template<typename Constant_T>
125
125
  inline auto& define_constant(std::string name, Constant_T value)
126
126
  {
127
127
  using Base_T = detail::remove_cv_recursive_t<Constant_T>;
128
- detail::protect(rb_define_const, this->value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
128
+ detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
129
129
  return *this;
130
130
  }
@@ -165,6 +165,10 @@ namespace Rice::detail
165
165
  T defaultValue = this->arg()->template defaultValue<T>();
166
166
  return this->toRuby_.convert(defaultValue);
167
167
  }
168
+ else
169
+ {
170
+ throw std::runtime_error("Default value not allowed for parameter " + this->arg()->name);
171
+ }
168
172
  }
169
173
  else
170
174
  {
@@ -154,6 +154,17 @@ namespace Rice::detail
154
154
  static inline std::string name = "Float";
155
155
  };
156
156
 
157
+ template<>
158
+ class RubyType<long double>
159
+ {
160
+ public:
161
+ using FromRuby_T = double(*)(VALUE);
162
+
163
+ static inline FromRuby_T fromRuby = rb_num2dbl;
164
+ static inline std::string packTemplate = "d*";
165
+ static inline std::string name = "Float";
166
+ };
167
+
157
168
  template<>
158
169
  class RubyType<void>
159
170
  {
@@ -13,6 +13,12 @@ namespace Rice::detail
13
13
  {
14
14
  return std::type_index(typeid(T));
15
15
  }
16
+ else if constexpr (std::is_reference_v<T>)
17
+ {
18
+ // For incomplete reference types, strip the reference and use pointer.
19
+ // Can't form T* when T is a reference type (pointer-to-reference is illegal).
20
+ return std::type_index(typeid(std::remove_reference_t<T>*));
21
+ }
16
22
  else
17
23
  {
18
24
  return std::type_index(typeid(T*));
@@ -404,6 +404,35 @@ namespace Rice::detail
404
404
  }
405
405
  };
406
406
 
407
+ template<>
408
+ struct Type<long double>
409
+ {
410
+ static bool verify()
411
+ {
412
+ return true;
413
+ }
414
+
415
+ static VALUE rubyKlass()
416
+ {
417
+ return rb_cFloat;
418
+ }
419
+ };
420
+
421
+ template<int N>
422
+ struct Type<long double[N]>
423
+ {
424
+ static bool verify()
425
+ {
426
+ define_buffer<long double>();
427
+ return true;
428
+ }
429
+
430
+ static VALUE rubyKlass()
431
+ {
432
+ return rb_cString;
433
+ }
434
+ };
435
+
407
436
  template<>
408
437
  struct Type<void>
409
438
  {
@@ -729,6 +729,86 @@ namespace Rice::detail
729
729
  Reference<double> reference_;
730
730
  };
731
731
 
732
+ // =========== long double ============
733
+ template<>
734
+ class From_Ruby<long double>
735
+ {
736
+ public:
737
+ From_Ruby() = default;
738
+
739
+ explicit From_Ruby(Arg* arg) : arg_(arg)
740
+ {}
741
+
742
+ long double is_convertible(VALUE value)
743
+ {
744
+ return FromRubyFundamental<long double>::is_convertible(value);
745
+ }
746
+
747
+ long double convert(VALUE value)
748
+ {
749
+ return FromRubyFundamental<long double>::convert(value);
750
+ }
751
+
752
+ private:
753
+ Arg* arg_ = nullptr;
754
+ };
755
+
756
+ template<>
757
+ class From_Ruby<long double&>
758
+ {
759
+ public:
760
+ using Reference_T = Reference<long double>;
761
+
762
+ From_Ruby() = default;
763
+
764
+ explicit From_Ruby(Arg* arg) : arg_(arg)
765
+ {}
766
+
767
+ long double is_convertible(VALUE value)
768
+ {
769
+ switch (rb_type(value))
770
+ {
771
+ case RUBY_T_DATA:
772
+ {
773
+ if (Data_Type<Reference_T>::is_descendant(value))
774
+ {
775
+ return Convertible::Exact;
776
+ }
777
+ [[fallthrough]];
778
+ }
779
+ default:
780
+ {
781
+ return FromRubyFundamental<long double>::is_convertible(value);
782
+ }
783
+ }
784
+ }
785
+
786
+ long double& convert(VALUE value)
787
+ {
788
+ switch (rb_type(value))
789
+ {
790
+ case RUBY_T_DATA:
791
+ {
792
+ if (Data_Type<Reference_T>::is_descendant(value))
793
+ {
794
+ Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
795
+ return reference->get();
796
+ }
797
+ [[fallthrough]];
798
+ }
799
+ default:
800
+ {
801
+ this->reference_ = Reference<long double>(value);
802
+ return this->reference_.get();
803
+ }
804
+ }
805
+ }
806
+
807
+ private:
808
+ Arg* arg_ = nullptr;
809
+ Reference<long double> reference_;
810
+ };
811
+
732
812
  // =========== float ============
733
813
  template<>
734
814
  class From_Ruby<float>
@@ -501,6 +501,62 @@ namespace Rice
501
501
  Arg* arg_ = nullptr;
502
502
  };
503
503
 
504
+ // =========== long double ============
505
+ template<>
506
+ class To_Ruby<long double>
507
+ {
508
+ public:
509
+ To_Ruby() = default;
510
+
511
+ explicit To_Ruby(Arg* arg) : arg_(arg)
512
+ {}
513
+
514
+ VALUE convert(const long double& native)
515
+ {
516
+ return protect(rb_float_new, native);
517
+ }
518
+
519
+ private:
520
+ Arg* arg_ = nullptr;
521
+ };
522
+
523
+ template<>
524
+ class To_Ruby<long double&>
525
+ {
526
+ public:
527
+ To_Ruby() = default;
528
+
529
+ explicit To_Ruby(Arg* arg) : arg_(arg)
530
+ {}
531
+
532
+ VALUE convert(const long double& native)
533
+ {
534
+ return protect(rb_float_new, native);
535
+ }
536
+
537
+ private:
538
+ Arg* arg_ = nullptr;
539
+ };
540
+
541
+ template<int N>
542
+ class To_Ruby<long double[N]>
543
+ {
544
+ public:
545
+ To_Ruby() = default;
546
+
547
+ explicit To_Ruby(Arg* arg) : arg_(arg)
548
+ {}
549
+
550
+ VALUE convert(long double data[N])
551
+ {
552
+ Buffer<long double> buffer(data, N);
553
+ Data_Object<Buffer<long double>> dataObject(std::move(buffer));
554
+ return dataObject.value();
555
+ }
556
+ private:
557
+ Arg* arg_ = nullptr;
558
+ };
559
+
504
560
  // =========== float ============
505
561
  template<>
506
562
  class To_Ruby<float>
data/test/test_Object.cpp CHANGED
@@ -97,12 +97,7 @@ TESTCASE(implicit_conversion_to_value)
97
97
  ASSERT_EQUAL(INT2NUM(42), (VALUE)Object(INT2NUM(42)));
98
98
  ASSERT_EQUAL(Qfalse, (VALUE)Object(Qfalse));
99
99
  ASSERT_EQUAL(Qundef, (VALUE)Object(Qundef));
100
-
101
- ASSERT_EXCEPTION_CHECK(
102
- std::runtime_error,
103
- (VALUE)Object(Qnil),
104
- ASSERT_EQUAL("Rice Object does not wrap a Ruby object", ex.what())
105
- );
100
+ ASSERT_EQUAL(Qnil, (VALUE)Object(Qnil));
106
101
  }
107
102
 
108
103
  TESTCASE(explicit_conversion_to_value)
@@ -111,12 +106,7 @@ TESTCASE(explicit_conversion_to_value)
111
106
  ASSERT_EQUAL(INT2NUM(42), Object(INT2NUM(42)).value());
112
107
  ASSERT_EQUAL(Qfalse, Object(Qfalse).value());
113
108
  ASSERT_EQUAL(Qundef, Object(Qundef).value());
114
-
115
- ASSERT_EXCEPTION_CHECK(
116
- std::runtime_error,
117
- Object(Qnil).value(),
118
- ASSERT_EQUAL("Rice Object does not wrap a Ruby object", ex.what())
119
- );
109
+ ASSERT_EQUAL(Qnil, Object(Qnil).value());
120
110
  }
121
111
 
122
112
  TESTCASE(class_of)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rice
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.11.0
4
+ version: 4.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Brannan