rice 4.7.0 → 4.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75730bdd1cda9ed1d24be45b32d1cbe92b6dca8e021fdb39a8b681403fc1814a
4
- data.tar.gz: eb653e187ef8d543007ad0ceb3e5712869d598466c21997d2fd759699742df19
3
+ metadata.gz: c8d106501ff928ca481358d579bffe110efebbd4a98f3de141b8a4e6a853b17a
4
+ data.tar.gz: 900e679ee80f32d547487133911dfa1ccdd087a41414fb44a1c8b144fec15278
5
5
  SHA512:
6
- metadata.gz: 7c6a0d269f24af26c836ca71a7684d410d823a6661a26af1bb1ddb205b65067258119d49bcadabe9aa806884a4505213e5489d5638cdd3420b4edccd59e49928
7
- data.tar.gz: 1a14760fb0e2903c594ae0e0a3d14077a806bf59c720323a30c6a8bc4958a0e35fd0c0436eedcd6b4a6451e8a7344098be0bab00113964127b4027c790159910
6
+ metadata.gz: 33837b467af9b734848a7ef09b552ed2ab25f7f86c6fdedbc8f6c85dc42137d2ca46e9fd812198b99baa4af94f1f659d15530f9ecf36a2e147d3ddfb5f3c02ff
7
+ data.tar.gz: 11bccd16adcb9a117a5ce80c91b219b1102a1fde56086542528a4684cedc84631261c6afb583dbebb0c25c3a2b1908c2196197f36c79cfc7db7322ab104d0388
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 4.7.1 (2025-10-28)
2
+ Updates:
3
+ * Update overload resolution to take into account function arguments that are tagged as buffers via Arg("").setBuffer().
4
+ * Make second parameter optional for Array#push and update docs
5
+ * Remove ostruct runtime dependency
6
+
1
7
  ## 4.7.0 (2025-10-22)
2
8
  Updates:
3
9
  * Refactor Native wrappers - functions, methods, attributes and procs - to enable introspection API
@@ -28,6 +34,7 @@ Breaking Changes:
28
34
  ```
29
35
  * You can no longer pass a Buffer<T> to an API that takes a pointer. Instead use Buffer<T>#data or Buffer<T>::release
30
36
  * The Rice_Init method has been removed.
37
+ * Array#push requires a second argument.
31
38
 
32
39
  ## 4.6.1 (2025-06-25)
33
40
  * Improve attribute handling. Correctly deal with non-copyable/assignable attributes and return references instead of copies of objects
data/bin/rice-doc.rb CHANGED
@@ -5,7 +5,6 @@ require_relative '../lib/rice'
5
5
  require_relative '../lib/rice/doc'
6
6
 
7
7
  # Now setup option parser
8
- require 'ostruct'
9
8
  require 'optparse'
10
9
 
11
10
  module Rice
@@ -51,7 +50,7 @@ module Rice
51
50
  end
52
51
 
53
52
  def parse_args
54
- @options = OpenStruct.new
53
+ @options = Struct.new(:exec, :extension, :output).new
55
54
  options.extension = nil
56
55
  options.output = nil
57
56
 
data/bin/rice-rbs.rb CHANGED
@@ -6,7 +6,6 @@ require 'bundler/setup'
6
6
  require 'rice'
7
7
 
8
8
  # Now setup option parser
9
- require 'ostruct'
10
9
  require 'optparse'
11
10
 
12
11
  module Rice
@@ -52,7 +51,7 @@ module Rice
52
51
  end
53
52
 
54
53
  def parse_args
55
- @options = OpenStruct.new
54
+ @options = Struct.new(:exec, :extension, :output).new
56
55
  options.extension = nil
57
56
  options.output = nil
58
57
 
@@ -1885,8 +1885,8 @@ namespace Rice
1885
1885
  * Example:
1886
1886
  * \code
1887
1887
  * Array a;
1888
- * a.push(String("some string"));
1889
- * a.push(42);
1888
+ * a.push(String("some string"), false);
1889
+ * a.push(42, false);
1890
1890
  * \endcode
1891
1891
  */
1892
1892
  class Array
@@ -1965,7 +1965,7 @@ namespace Rice
1965
1965
  * \return the object which was pushed onto the array.
1966
1966
  */
1967
1967
  template<typename T>
1968
- Object push(T&& obj, bool takeOwnership);
1968
+ Object push(T&& obj, bool takeOwnership = false);
1969
1969
 
1970
1970
  //! Pop an element from the end of the array
1971
1971
  /*! \return the object which was popped from the array, or Qnil if
@@ -8502,7 +8502,6 @@ namespace Rice::detail
8502
8502
  return result;
8503
8503
  }
8504
8504
 
8505
-
8506
8505
  inline const std::vector<std::unique_ptr<Native>>& NativeRegistry::lookup(VALUE klass, ID methodId)
8507
8506
  {
8508
8507
  if (rb_type(klass) == T_ICLASS)
@@ -9515,10 +9514,6 @@ namespace Rice::detail
9515
9514
  // Execute the function but make sure to catch any C++ exceptions!
9516
9515
  return cpp_protect([&]
9517
9516
  {
9518
- Identifier id(methodId);
9519
- std::string methodName = id.str();
9520
- std::string className = rb_class2name(klass);
9521
-
9522
9517
  const std::vector<std::unique_ptr<Native>>& natives = Registries::instance.natives.lookup(klass, methodId);
9523
9518
 
9524
9519
  if (natives.size() == 1)
@@ -9631,10 +9626,10 @@ namespace Rice::detail
9631
9626
 
9632
9627
  if constexpr (std::is_pointer_v<T> && std::is_fundamental_v<std::remove_pointer_t<T>>)
9633
9628
  {
9634
- Type<Pointer<std::remove_pointer_t<T>>>::verify();
9635
- Type<Buffer<std::remove_pointer_t<T>>>::verify();
9629
+ Type<Pointer<Base_T>>::verify();
9630
+ Type<Buffer<Base_T>>::verify();
9636
9631
  }
9637
- if constexpr (std::is_array_v<T>)
9632
+ else if constexpr (std::is_array_v<T>)
9638
9633
  {
9639
9634
  Type<Pointer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
9640
9635
  Type<Buffer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
@@ -12742,6 +12737,12 @@ namespace Rice::detail
12742
12737
  class From_Ruby<Symbol>
12743
12738
  {
12744
12739
  public:
12740
+ From_Ruby() = default;
12741
+
12742
+ explicit From_Ruby(Arg* arg) : arg_(arg)
12743
+ {
12744
+ }
12745
+
12745
12746
  Convertible is_convertible(VALUE value)
12746
12747
  {
12747
12748
  switch (rb_type(value))
@@ -12761,6 +12762,9 @@ namespace Rice::detail
12761
12762
  {
12762
12763
  return Symbol(value);
12763
12764
  }
12765
+
12766
+ private:
12767
+ Arg* arg_ = nullptr;
12764
12768
  };
12765
12769
  }
12766
12770
 
@@ -14021,16 +14025,17 @@ namespace Rice
14021
14025
  template <typename T>
14022
14026
  Exception create_type_exception(VALUE value)
14023
14027
  {
14024
- if constexpr (std::is_pointer_v<T>)
14028
+ if (Data_Type<T>::is_bound())
14025
14029
  {
14026
- return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
14027
- detail::protect(rb_class2name, Data_Type<Pointer<std::remove_cv_t<std::remove_pointer_t<T>>>>::klass().value()),
14030
+ return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
14031
+ detail::protect(rb_class2name, Data_Type<T>::klass().value()),
14028
14032
  detail::protect(rb_obj_classname, value));
14029
14033
  }
14030
14034
  else
14031
14035
  {
14032
- return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
14033
- detail::protect(rb_class2name, Data_Type<detail::intrinsic_type<T>>::klass().value()),
14036
+ detail::TypeMapper<T> typeMapper;
14037
+ return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
14038
+ typeMapper.simplifiedName().c_str(),
14034
14039
  detail::protect(rb_obj_classname, value));
14035
14040
  }
14036
14041
  }
@@ -14506,6 +14511,7 @@ namespace Rice::detail
14506
14511
  "Please include rice/stl.hpp header for STL support");
14507
14512
 
14508
14513
  using Intrinsic_T = intrinsic_type<T>;
14514
+ using Pointer_T = Pointer<remove_cv_recursive_t<T>>;
14509
14515
 
14510
14516
  public:
14511
14517
  From_Ruby() = default;
@@ -14516,17 +14522,19 @@ namespace Rice::detail
14516
14522
 
14517
14523
  Convertible is_convertible(VALUE value)
14518
14524
  {
14525
+ bool isBuffer = this->arg_->isBuffer();
14526
+
14519
14527
  switch (rb_type(value))
14520
14528
  {
14521
14529
  case RUBY_T_NIL:
14522
14530
  return Convertible::Exact;
14523
14531
  break;
14524
14532
  case RUBY_T_DATA:
14525
- if (Data_Type<T>::is_descendant(value))
14533
+ if (Data_Type<T>::is_descendant(value) && !isBuffer)
14526
14534
  {
14527
14535
  return Convertible::Exact;
14528
14536
  }
14529
- else if (Data_Type<Pointer<T>>::is_descendant(value))
14537
+ else if (Data_Type<Pointer_T>::is_descendant(value))
14530
14538
  {
14531
14539
  return Convertible::Exact;
14532
14540
  }
@@ -14539,6 +14547,7 @@ namespace Rice::detail
14539
14547
  T* convert(VALUE value)
14540
14548
  {
14541
14549
  bool isOwner = this->arg_ && this->arg_->isOwner();
14550
+ bool isBuffer = this->arg_ && this->arg_->isBuffer();
14542
14551
 
14543
14552
  switch (rb_type(value))
14544
14553
  {
@@ -14549,19 +14558,26 @@ namespace Rice::detail
14549
14558
  }
14550
14559
  case RUBY_T_DATA:
14551
14560
  {
14552
- if (Data_Type<T>::is_descendant(value))
14561
+ if (Data_Type<T>::is_descendant(value) && !isBuffer)
14553
14562
  {
14554
14563
  return detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), isOwner);
14555
14564
  }
14556
- else if (Data_Type<Pointer<T>>::is_descendant(value))
14565
+ else if (Data_Type<Pointer_T>::is_descendant(value))
14557
14566
  {
14558
- return detail::unwrap<T>(value, Data_Type<Pointer<T>>::ruby_data_type(), isOwner);
14567
+ return detail::unwrap<T>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
14559
14568
  }
14560
14569
  [[fallthrough]];
14561
14570
  }
14562
14571
  default:
14563
14572
  {
14564
- throw create_type_exception<T*>(value);
14573
+ if (isBuffer || std::is_fundamental_v<T>)
14574
+ {
14575
+ throw create_type_exception<Pointer_T>(value);
14576
+ }
14577
+ else
14578
+ {
14579
+ throw create_type_exception<T>(value);
14580
+ }
14565
14581
  }
14566
14582
  }
14567
14583
  }
@@ -14628,6 +14644,7 @@ namespace Rice::detail
14628
14644
  "Please include rice/stl.hpp header for STL support");
14629
14645
 
14630
14646
  using Intrinsic_T = intrinsic_type<T>;
14647
+ using Pointer_T = Pointer<remove_cv_recursive_t<T>*>;
14631
14648
  public:
14632
14649
  From_Ruby() = default;
14633
14650
 
@@ -14637,14 +14654,19 @@ namespace Rice::detail
14637
14654
 
14638
14655
  Convertible is_convertible(VALUE value)
14639
14656
  {
14657
+ bool isBuffer = this->arg_ && this->arg_->isBuffer();
14658
+
14640
14659
  switch (rb_type(value))
14641
14660
  {
14642
- case RUBY_T_DATA:
14643
- return Data_Type<Pointer<T*>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
14644
- break;
14645
14661
  case RUBY_T_NIL:
14646
14662
  return Convertible::Exact;
14647
14663
  break;
14664
+ case RUBY_T_DATA:
14665
+ if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
14666
+ {
14667
+ return Convertible::Exact;
14668
+ }
14669
+ [[fallthrough]];
14648
14670
  default:
14649
14671
  return Convertible::None;
14650
14672
  }
@@ -14653,23 +14675,34 @@ namespace Rice::detail
14653
14675
  T** convert(VALUE value)
14654
14676
  {
14655
14677
  bool isOwner = this->arg_ && this->arg_->isOwner();
14678
+ bool isBuffer = this->arg_ && this->arg_->isBuffer();
14656
14679
 
14657
14680
  switch (rb_type(value))
14658
14681
  {
14659
- case RUBY_T_DATA:
14660
- {
14661
- T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer<T*>>::ruby_data_type(), isOwner);
14662
- return result;
14663
- break;
14664
- }
14665
14682
  case RUBY_T_NIL:
14666
14683
  {
14667
14684
  return nullptr;
14668
14685
  break;
14669
14686
  }
14687
+ case RUBY_T_DATA:
14688
+ {
14689
+ if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
14690
+ {
14691
+ T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
14692
+ return result;
14693
+ }
14694
+ [[fallthrough]];
14695
+ }
14670
14696
  default:
14671
14697
  {
14672
- throw create_type_exception<T**>(value);
14698
+ if (isBuffer)
14699
+ {
14700
+ throw create_type_exception<Pointer_T>(value);
14701
+ }
14702
+ else
14703
+ {
14704
+ throw create_type_exception<T**>(value);
14705
+ }
14673
14706
  }
14674
14707
  }
14675
14708
  }
data/include/rice/stl.hpp CHANGED
@@ -445,20 +445,38 @@ namespace Rice::detail
445
445
  class To_Ruby<std::string_view>
446
446
  {
447
447
  public:
448
+ To_Ruby() = default;
449
+
450
+ explicit To_Ruby(Arg* arg) : arg_(arg)
451
+ {
452
+ }
453
+
448
454
  VALUE convert(std::string_view const& x)
449
455
  {
450
456
  return detail::protect(rb_external_str_new, x.data(), (long)x.size());
451
457
  }
458
+
459
+ private:
460
+ Arg* arg_ = nullptr;
452
461
  };
453
462
 
454
463
  template<>
455
464
  class To_Ruby<std::string_view&>
456
465
  {
457
466
  public:
467
+ To_Ruby() = default;
468
+
469
+ explicit To_Ruby(Arg* arg) : arg_(arg)
470
+ {
471
+ }
472
+
458
473
  VALUE convert(std::string_view const& x)
459
474
  {
460
475
  return detail::protect(rb_external_str_new, x.data(), (long)x.size());
461
476
  }
477
+
478
+ private:
479
+ Arg* arg_ = nullptr;
462
480
  };
463
481
 
464
482
  template<>
data/lib/rice/rbs.rb CHANGED
@@ -53,7 +53,7 @@ module Rice
53
53
  "attr_reader"
54
54
  else
55
55
  "attr_writer"
56
- end
56
+ end
57
57
  "#{attr_type} #{native_attributes.first.name}: #{native_attributes.first.return_type}"
58
58
  end
59
59
 
@@ -82,7 +82,7 @@ module Rice
82
82
  end
83
83
 
84
84
  def template
85
- content = <<~EOS
85
+ <<~EOS
86
86
  module <%= klass.name.split("::")[0..-2].join("::") %>
87
87
  class <%= klass.name.split("::").last %>
88
88
  <%- native_functions.each do |name, functions| -%>
data/lib/rice/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rice
2
- VERSION = "4.7.0"
2
+ VERSION = "4.7.1"
3
3
  end
data/rice/Data_Object.ipp CHANGED
@@ -6,16 +6,17 @@ namespace Rice
6
6
  template <typename T>
7
7
  Exception create_type_exception(VALUE value)
8
8
  {
9
- if constexpr (std::is_pointer_v<T>)
9
+ if (Data_Type<T>::is_bound())
10
10
  {
11
- return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
12
- detail::protect(rb_class2name, Data_Type<Pointer<std::remove_cv_t<std::remove_pointer_t<T>>>>::klass().value()),
11
+ return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
12
+ detail::protect(rb_class2name, Data_Type<T>::klass().value()),
13
13
  detail::protect(rb_obj_classname, value));
14
14
  }
15
15
  else
16
16
  {
17
- return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
18
- detail::protect(rb_class2name, Data_Type<detail::intrinsic_type<T>>::klass().value()),
17
+ detail::TypeMapper<T> typeMapper;
18
+ return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
19
+ typeMapper.simplifiedName().c_str(),
19
20
  detail::protect(rb_obj_classname, value));
20
21
  }
21
22
  }
@@ -491,6 +492,7 @@ namespace Rice::detail
491
492
  "Please include rice/stl.hpp header for STL support");
492
493
 
493
494
  using Intrinsic_T = intrinsic_type<T>;
495
+ using Pointer_T = Pointer<remove_cv_recursive_t<T>>;
494
496
 
495
497
  public:
496
498
  From_Ruby() = default;
@@ -501,17 +503,19 @@ namespace Rice::detail
501
503
 
502
504
  Convertible is_convertible(VALUE value)
503
505
  {
506
+ bool isBuffer = this->arg_->isBuffer();
507
+
504
508
  switch (rb_type(value))
505
509
  {
506
510
  case RUBY_T_NIL:
507
511
  return Convertible::Exact;
508
512
  break;
509
513
  case RUBY_T_DATA:
510
- if (Data_Type<T>::is_descendant(value))
514
+ if (Data_Type<T>::is_descendant(value) && !isBuffer)
511
515
  {
512
516
  return Convertible::Exact;
513
517
  }
514
- else if (Data_Type<Pointer<T>>::is_descendant(value))
518
+ else if (Data_Type<Pointer_T>::is_descendant(value))
515
519
  {
516
520
  return Convertible::Exact;
517
521
  }
@@ -524,6 +528,7 @@ namespace Rice::detail
524
528
  T* convert(VALUE value)
525
529
  {
526
530
  bool isOwner = this->arg_ && this->arg_->isOwner();
531
+ bool isBuffer = this->arg_ && this->arg_->isBuffer();
527
532
 
528
533
  switch (rb_type(value))
529
534
  {
@@ -534,19 +539,26 @@ namespace Rice::detail
534
539
  }
535
540
  case RUBY_T_DATA:
536
541
  {
537
- if (Data_Type<T>::is_descendant(value))
542
+ if (Data_Type<T>::is_descendant(value) && !isBuffer)
538
543
  {
539
544
  return detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), isOwner);
540
545
  }
541
- else if (Data_Type<Pointer<T>>::is_descendant(value))
546
+ else if (Data_Type<Pointer_T>::is_descendant(value))
542
547
  {
543
- return detail::unwrap<T>(value, Data_Type<Pointer<T>>::ruby_data_type(), isOwner);
548
+ return detail::unwrap<T>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
544
549
  }
545
550
  [[fallthrough]];
546
551
  }
547
552
  default:
548
553
  {
549
- throw create_type_exception<T*>(value);
554
+ if (isBuffer || std::is_fundamental_v<T>)
555
+ {
556
+ throw create_type_exception<Pointer_T>(value);
557
+ }
558
+ else
559
+ {
560
+ throw create_type_exception<T>(value);
561
+ }
550
562
  }
551
563
  }
552
564
  }
@@ -613,6 +625,7 @@ namespace Rice::detail
613
625
  "Please include rice/stl.hpp header for STL support");
614
626
 
615
627
  using Intrinsic_T = intrinsic_type<T>;
628
+ using Pointer_T = Pointer<remove_cv_recursive_t<T>*>;
616
629
  public:
617
630
  From_Ruby() = default;
618
631
 
@@ -622,14 +635,19 @@ namespace Rice::detail
622
635
 
623
636
  Convertible is_convertible(VALUE value)
624
637
  {
638
+ bool isBuffer = this->arg_ && this->arg_->isBuffer();
639
+
625
640
  switch (rb_type(value))
626
641
  {
627
- case RUBY_T_DATA:
628
- return Data_Type<Pointer<T*>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
629
- break;
630
642
  case RUBY_T_NIL:
631
643
  return Convertible::Exact;
632
644
  break;
645
+ case RUBY_T_DATA:
646
+ if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
647
+ {
648
+ return Convertible::Exact;
649
+ }
650
+ [[fallthrough]];
633
651
  default:
634
652
  return Convertible::None;
635
653
  }
@@ -638,23 +656,34 @@ namespace Rice::detail
638
656
  T** convert(VALUE value)
639
657
  {
640
658
  bool isOwner = this->arg_ && this->arg_->isOwner();
659
+ bool isBuffer = this->arg_ && this->arg_->isBuffer();
641
660
 
642
661
  switch (rb_type(value))
643
662
  {
644
- case RUBY_T_DATA:
645
- {
646
- T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer<T*>>::ruby_data_type(), isOwner);
647
- return result;
648
- break;
649
- }
650
663
  case RUBY_T_NIL:
651
664
  {
652
665
  return nullptr;
653
666
  break;
654
667
  }
668
+ case RUBY_T_DATA:
669
+ {
670
+ if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
671
+ {
672
+ T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
673
+ return result;
674
+ }
675
+ [[fallthrough]];
676
+ }
655
677
  default:
656
678
  {
657
- throw create_type_exception<T**>(value);
679
+ if (isBuffer)
680
+ {
681
+ throw create_type_exception<Pointer_T>(value);
682
+ }
683
+ else
684
+ {
685
+ throw create_type_exception<T**>(value);
686
+ }
658
687
  }
659
688
  }
660
689
  }
@@ -12,8 +12,8 @@ namespace Rice
12
12
  * Example:
13
13
  * \code
14
14
  * Array a;
15
- * a.push(String("some string"));
16
- * a.push(42);
15
+ * a.push(String("some string"), false);
16
+ * a.push(42, false);
17
17
  * \endcode
18
18
  */
19
19
  class Array
@@ -92,7 +92,7 @@ namespace Rice
92
92
  * \return the object which was pushed onto the array.
93
93
  */
94
94
  template<typename T>
95
- Object push(T&& obj, bool takeOwnership);
95
+ Object push(T&& obj, bool takeOwnership = false);
96
96
 
97
97
  //! Pop an element from the end of the array
98
98
  /*! \return the object which was popped from the array, or Qnil if
@@ -104,6 +104,12 @@ namespace Rice::detail
104
104
  class From_Ruby<Symbol>
105
105
  {
106
106
  public:
107
+ From_Ruby() = default;
108
+
109
+ explicit From_Ruby(Arg* arg) : arg_(arg)
110
+ {
111
+ }
112
+
107
113
  Convertible is_convertible(VALUE value)
108
114
  {
109
115
  switch (rb_type(value))
@@ -123,5 +129,8 @@ namespace Rice::detail
123
129
  {
124
130
  return Symbol(value);
125
131
  }
132
+
133
+ private:
134
+ Arg* arg_ = nullptr;
126
135
  };
127
136
  }
@@ -66,10 +66,6 @@ namespace Rice::detail
66
66
  // Execute the function but make sure to catch any C++ exceptions!
67
67
  return cpp_protect([&]
68
68
  {
69
- Identifier id(methodId);
70
- std::string methodName = id.str();
71
- std::string className = rb_class2name(klass);
72
-
73
69
  const std::vector<std::unique_ptr<Native>>& natives = Registries::instance.natives.lookup(klass, methodId);
74
70
 
75
71
  if (natives.size() == 1)
@@ -182,10 +178,10 @@ namespace Rice::detail
182
178
 
183
179
  if constexpr (std::is_pointer_v<T> && std::is_fundamental_v<std::remove_pointer_t<T>>)
184
180
  {
185
- Type<Pointer<std::remove_pointer_t<T>>>::verify();
186
- Type<Buffer<std::remove_pointer_t<T>>>::verify();
181
+ Type<Pointer<Base_T>>::verify();
182
+ Type<Buffer<Base_T>>::verify();
187
183
  }
188
- if constexpr (std::is_array_v<T>)
184
+ else if constexpr (std::is_array_v<T>)
189
185
  {
190
186
  Type<Pointer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
191
187
  Type<Buffer<std::remove_extent_t<remove_cv_recursive_t<T>>>>::verify();
@@ -59,7 +59,6 @@ namespace Rice::detail
59
59
  return result;
60
60
  }
61
61
 
62
-
63
62
  inline const std::vector<std::unique_ptr<Native>>& NativeRegistry::lookup(VALUE klass, ID methodId)
64
63
  {
65
64
  if (rb_type(klass) == T_ICLASS)
@@ -20,20 +20,38 @@ namespace Rice::detail
20
20
  class To_Ruby<std::string_view>
21
21
  {
22
22
  public:
23
+ To_Ruby() = default;
24
+
25
+ explicit To_Ruby(Arg* arg) : arg_(arg)
26
+ {
27
+ }
28
+
23
29
  VALUE convert(std::string_view const& x)
24
30
  {
25
31
  return detail::protect(rb_external_str_new, x.data(), (long)x.size());
26
32
  }
33
+
34
+ private:
35
+ Arg* arg_ = nullptr;
27
36
  };
28
37
 
29
38
  template<>
30
39
  class To_Ruby<std::string_view&>
31
40
  {
32
41
  public:
42
+ To_Ruby() = default;
43
+
44
+ explicit To_Ruby(Arg* arg) : arg_(arg)
45
+ {
46
+ }
47
+
33
48
  VALUE convert(std::string_view const& x)
34
49
  {
35
50
  return detail::protect(rb_external_str_new, x.data(), (long)x.size());
36
51
  }
52
+
53
+ private:
54
+ Arg* arg_ = nullptr;
37
55
  };
38
56
 
39
57
  template<>
data/rice.gemspec CHANGED
@@ -67,7 +67,6 @@ Ruby extensions with C++ easier.
67
67
  ]
68
68
 
69
69
  s.required_ruby_version = ">= 3.1"
70
- s.add_dependency "ostruct"
71
70
  s.add_development_dependency "bundler"
72
71
  s.add_development_dependency "rake"
73
72
  s.add_development_dependency "minitest"
data/test/test_Buffer.cpp CHANGED
@@ -594,7 +594,7 @@ TESTCASE(pass_objects)
594
594
  {
595
595
  Module m = define_module("Testing");
596
596
  m.define_module_function<size_t(*)(const MyClassBuf*, size_t)>("sum_ids", &sumIds, Arg("myClasses").setBuffer());
597
- m.define_module_function<size_t(*)(const MyClassBuf**, size_t)>("sum_ids_ptr", &sumIds);
597
+ m.define_module_function<size_t(*)(const MyClassBuf**, size_t)>("sum_ids_ptr", &sumIds, Arg("myClasses").setBuffer());
598
598
 
599
599
  define_class_under<MyClassBuf>(m, "MyClassBuf").
600
600
  define_constructor(Constructor<MyClassBuf, int>()).
@@ -95,7 +95,7 @@ TESTCASE(data_object_construct_from_ruby_object_and_wrong_class)
95
95
  ASSERT_EXCEPTION_CHECK(
96
96
  Exception,
97
97
  Data_Object<Bar> bar(wrapped_foo),
98
- ASSERT_EQUAL("Wrong argument type. Expected: Bar. Received: MyDataType.", ex.what()));
98
+ ASSERT_EQUAL("Wrong argument type. Expected Bar. Received MyDataType.", ex.what()));
99
99
  }
100
100
 
101
101
  TESTCASE(data_object_copy_construct)
@@ -871,7 +871,8 @@ TESTCASE(pointer_of_ranges_wrong)
871
871
  .define_attr("x", &RangesTest::RangeCustom::x)
872
872
  .define_attr("y", &RangesTest::RangeCustom::y);
873
873
 
874
- m.define_module_function<int(*)(const RangesTest::RangeCustom*, int)>("sum_ranges_wrong", RangesTest::sumRanges);
874
+ m.define_module_function<int(*)(const RangesTest::RangeCustom*, int)>("sum_ranges_wrong", RangesTest::sumRanges,
875
+ Arg("ranges").setBuffer());
875
876
 
876
877
  std::string code = R"(range1 = RangeCustom.new(1, 2)
877
878
  range2 = RangeCustom.new(3, 4)
@@ -883,7 +884,7 @@ TESTCASE(pointer_of_ranges_wrong)
883
884
  ASSERT_EXCEPTION_CHECK(
884
885
  Rice::Exception,
885
886
  m.module_eval(code),
886
- ASSERT_EQUAL("Wrong argument type. Expected: Rice::Pointer≺RangesTest꞉꞉RangeCustom≻. Received: Rice::Buffer≺RangesTest꞉꞉RangeCustom≻.", ex.what())
887
+ ASSERT_EQUAL("Wrong argument type. Expected Rice::Pointer≺RangesTest꞉꞉RangeCustom≻. Received Rice::Buffer≺RangesTest꞉꞉RangeCustom≻.", ex.what())
887
888
  );
888
889
  }
889
890
 
@@ -200,7 +200,7 @@ TESTCASE(signed_char_pointer)
200
200
  ASSERT_EXCEPTION_CHECK(
201
201
  Exception,
202
202
  fromRuby.convert(rb_float_new(11.11)),
203
- ASSERT_EQUAL("Wrong argument type. Expected: Rice::Pointer≺signed char≻. Received: Float.", ex.what())
203
+ ASSERT_EQUAL("Wrong argument type. Expected Rice::Pointer≺signed char≻. Received Float.", ex.what())
204
204
  );
205
205
  }
206
206
 
@@ -279,7 +279,7 @@ TESTCASE(unsigned_char_pointer)
279
279
  ASSERT_EXCEPTION_CHECK(
280
280
  Exception,
281
281
  detail::From_Ruby<const char*>().convert(rb_float_new(11.11)),
282
- ASSERT_EQUAL("Wrong argument type. Expected: Rice::Pointer≺char≻. Received: Float.", ex.what())
282
+ ASSERT_EQUAL("Wrong argument type. Expected Rice::Pointer≺char≻. Received Float.", ex.what())
283
283
  );
284
284
  }
285
285
 
@@ -414,7 +414,7 @@ TESTCASE(float_array_array)
414
414
  {
415
415
  Module m = define_module("Testing");
416
416
 
417
- m.define_singleton_function("array_array_to_string", &arrayofArraysToString<float>);
417
+ m.define_singleton_function("array_array_to_string", &arrayofArraysToString<float>, Arg("buffer").setBuffer());
418
418
 
419
419
  std::string code = R"(buffer = Rice::Buffer≺float∗≻.new([[1.1, 2.2], [3.3, 4.4], [5.5, 6.6]])
420
420
  array_array_to_string(buffer.data, buffer.size, 2))";
@@ -441,7 +441,7 @@ TESTCASE(float_array_array)
441
441
  ASSERT_EXCEPTION_CHECK(
442
442
  Exception,
443
443
  m.module_eval(code),
444
- ASSERT_EQUAL("Wrong argument type. Expected: Rice::Pointer≺float∗≻. Received: Array.", ex.what())
444
+ ASSERT_EQUAL("Wrong argument type. Expected Rice::Pointer≺float∗≻. Received Array.", ex.what())
445
445
  );
446
446
  }
447
447
 
@@ -647,7 +647,7 @@ TESTCASE(int_conversion_6)
647
647
  Class c = define_class<MyClass3>("MyClass3").
648
648
  define_constructor(Constructor<MyClass3>()).
649
649
  define_method<std::string(MyClass3::*)(unsigned char)>("run", &MyClass3::run).
650
- define_method<std::string(MyClass3::*)(unsigned char*)>("run", &MyClass3::run);
650
+ define_method<std::string(MyClass3::*)(unsigned char*)>("run", &MyClass3::run, Arg("value").setBuffer());
651
651
 
652
652
  Module m = define_module("Testing");
653
653
 
@@ -707,8 +707,8 @@ TESTCASE(NonConstRef)
707
707
  Module m = define_module("Testing");
708
708
 
709
709
  std::string code = R"(my_class4 = MyClass4.new
710
- my_class5 = MyClass5.new(my_class4)
711
- my_class5.result)";
710
+ my_class5 = MyClass5.new(my_class4)
711
+ my_class5.result)";
712
712
  String result = m.module_eval(code);
713
713
  ASSERT_EQUAL("non-const ref", result.str());
714
714
  }
@@ -726,8 +726,8 @@ TESTCASE(ConstRef)
726
726
  Module m = define_module("Testing");
727
727
 
728
728
  std::string code = R"(my_class4 = MyClass4.const_instance
729
- my_class5 = MyClass5.new(my_class4)
730
- my_class5.result)";
729
+ my_class5 = MyClass5.new(my_class4)
730
+ my_class5.result)";
731
731
  String result = m.module_eval(code);
732
732
  ASSERT_EQUAL("const ref", result.str());
733
733
  }
@@ -799,8 +799,56 @@ TESTCASE(ConstPointer)
799
799
  Module m = define_module("Testing");
800
800
 
801
801
  std::string code = R"(my_class6 = MyClass6.const_instance
802
- my_class7 = MyClass7.new(my_class6)
803
- my_class7.result)";
802
+ my_class7 = MyClass7.new(my_class6)
803
+ my_class7.result)";
804
804
  String result = m.module_eval(code);
805
805
  ASSERT_EQUAL("const pointer", result.str());
806
806
  }
807
+
808
+ namespace
809
+ {
810
+ std::string pointer(const MyClass6* data)
811
+ {
812
+ return "pointer";
813
+ }
814
+
815
+ std::string pointer(MyClass6* data)
816
+ {
817
+ return "pointerBuffer";
818
+ }
819
+ }
820
+
821
+ TESTCASE(PointerNotBuffer)
822
+ {
823
+ Module m = define_module("Testing");
824
+
825
+ define_class<MyClass6>("MyClass").
826
+ define_constructor(Constructor<MyClass6>());
827
+
828
+ m.define_module_function<std::string(*)(const MyClass6*)>("pointer", pointer).
829
+ define_module_function<std::string(*)(MyClass6*)>("pointer", pointer, Arg("data").setBuffer());
830
+
831
+ std::string code = R"(my_class6 = MyClass6.new
832
+ pointer(my_class6))";
833
+
834
+ String result = m.module_eval(code);
835
+ ASSERT_EQUAL("pointer", result.str());
836
+ }
837
+
838
+ TESTCASE(PointerBuffer)
839
+ {
840
+ Module m = define_module("Testing");
841
+
842
+ define_class<MyClass6>("MyClass").
843
+ define_constructor(Constructor<MyClass6>());
844
+
845
+ m.define_function<std::string(*)(const MyClass6*)>("pointer", pointer).
846
+ define_function<std::string(*)(MyClass6*)>("pointer", pointer, Arg("data").setBuffer());
847
+
848
+ std::string code = R"(my_class6 = MyClass6.new
849
+ buffer = Rice::Buffer≺AnonymousNamespace꞉꞉MyClass6≻.new(my_class6)
850
+ pointer(buffer.data))";
851
+
852
+ String result = m.module_eval(code);
853
+ ASSERT_EQUAL("pointerBuffer", result.str());
854
+ }
@@ -91,3 +91,13 @@ TESTCASE(std_string_view_from_ruby_refefence)
91
91
  string.instance_eval("self[1] = 'a'");
92
92
  //ASSERT_EQUAL("tast", view);
93
93
  }
94
+
95
+ namespace {
96
+ std::string_view testStringViewReturn(Object self) {
97
+ return "test";
98
+ }
99
+ }
100
+
101
+ TESTCASE(use_string_view_in_wrapped_function) {
102
+ define_global_function("test_string_view_return", &testStringViewReturn);
103
+ }
data/test/test_Symbol.cpp CHANGED
@@ -73,3 +73,15 @@ TESTCASE(to_id)
73
73
  Symbol symbol("Foo");
74
74
  ASSERT_EQUAL(Identifier("Foo"), symbol.to_id());
75
75
  }
76
+
77
+ namespace
78
+ {
79
+ void testSymbolArg(Object self, Symbol string)
80
+ {
81
+ }
82
+ }
83
+
84
+ TESTCASE(use_symbol_in_wrapped_function)
85
+ {
86
+ define_global_function("test_symbol_arg", &testSymbolArg);
87
+ }
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.7.0
4
+ version: 4.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Brannan
@@ -11,20 +11,6 @@ bindir: bin
11
11
  cert_chain: []
12
12
  date: 1980-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: ostruct
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: '0'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- version: '0'
28
14
  - !ruby/object:Gem::Dependency
29
15
  name: bundler
30
16
  requirement: !ruby/object:Gem::Requirement