rcx 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4074c5868fd711ee67726acd364d4aa243c5aeaf9fad6232756e9c1fde7539e3
4
- data.tar.gz: e38a49e450466554a5845189cf2ae51ba31665f18389bf9a8d1a052fe6858353
3
+ metadata.gz: 422a1c5bd974518c00e3a6c0ca86ac38f6c62ff06dd56acf0971973f215208bc
4
+ data.tar.gz: 8ecbbb1e288c7df1ebdb317f64c1c2656faf50044c4e6d06c598a6789d21906d
5
5
  SHA512:
6
- metadata.gz: cb13a7ca26f4caf50b3ad8038044f6abf7f932e612e1047df7c54bc543af07a4400a5f68fc64f37406eedff1234de7e99a58583a073c0cf4cbae916c0b03cdd8
7
- data.tar.gz: 918833acbc1d6d1bc2b5c9678533ccd6a8bbdd8f5a6b2b87e18e0baf12443eb3887cb2b8b7ca5349f897e37eb9d0a2c06381e4501870db5e00c25317cc76a9f0
6
+ metadata.gz: ec21a72b07c85b513459908b61733ee68c61c3116729ed87209a603666ed2396edb0ab140449db0d16185a183215dfb750c5e9ae8f5af5c3652accd63196dad6
7
+ data.tar.gz: 4d3bbb65011e6e2649da175130f22cd9bcf4bbbd95830452e06bad119d02b3904e2e514bc4aac05f92e32729bc463faa865ea6d6c4bccbd061a00b39cedb8d7a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  ## UNRELEASED
2
2
 
3
+ ## v0.4.0 (2025-09-03)
4
+ - Renamed `rcx::arg` namespace to `rcx::args` to prevent conflit with `rcx::arg::arg`.
5
+
3
6
  ## v0.3.1 (2025-09-02)
4
7
  - Now `extconf.rb`'s can only `require 'rcx/mkmf/c++20'` to enable RCX.
5
8
 
data/Rakefile CHANGED
@@ -39,6 +39,6 @@ task :yarn_install do
39
39
  end
40
40
 
41
41
  desc 'Format the source code'
42
- task :format => FileList['**/*.hpp'] do |t|
42
+ task :format => FileList['**/*.[ch]pp'] do |t|
43
43
  sh 'clang-format', '-i', *t.prerequisites
44
44
  end
data/examples/class.cpp CHANGED
@@ -3,7 +3,7 @@
3
3
  #include <rcx/rcx.hpp>
4
4
 
5
5
  void Init_examples_class() {
6
- using namespace rcx::arg;
6
+ using namespace rcx::args;
7
7
 
8
8
  auto ruby = rcx::Ruby::get();
9
9
  auto cls =
@@ -67,6 +67,10 @@ namespace rcx {
67
67
  /// Concepts
68
68
  ///
69
69
  namespace concepts {
70
+ /// Specifies the type `void`.
71
+ template <typename T>
72
+ concept Void = std::is_void_v<T>;
73
+
70
74
  template <typename T>
71
75
  concept StringLike = requires {
72
76
  typename std::remove_cvref_t<T>::value_type;
@@ -286,7 +290,7 @@ namespace rcx {
286
290
  /// Specifies the types that can be converted from Ruby values.
287
291
  ///
288
292
  template <typename T>
289
- concept ConvertibleFromValue = requires(Value v) { from_Value<T>(v); };
293
+ concept ConvertibleFromValue = !std::is_void_v<T> && requires(Value v) { from_Value<T>(v); };
290
294
 
291
295
  /// Specifies the types that can be converted into Ruby values.
292
296
  ///
@@ -316,7 +320,7 @@ namespace rcx {
316
320
 
317
321
  /// Argument parsing.
318
322
  ///
319
- namespace arg {
323
+ namespace args {
320
324
  template <concepts::ConvertibleFromValue T = Value> struct Self {
321
325
  using ResultType = detail::wrap_ref_t<T>;
322
326
  static ResultType parse(Ruby &, Value self, std::span<Value> &args);
@@ -534,10 +538,40 @@ namespace rcx {
534
538
  ClassT<Derived> get_class() const;
535
539
  Derived freeze() const;
536
540
 
541
+ /// Defines a singleton method for the object.
542
+ ///
543
+ /// @warning Defining a method this way allocates a resource that will never be
544
+ /// garbage-collected.
545
+ ///
546
+ /// @tparam Self The type of the receiver.
547
+ /// @tparam ArgSpec The types of the method arguments.
548
+ /// @param mid The name of the method.
549
+ /// @param function The C++ function to be invoked. It should accept `Self` as
550
+ /// the first argument, followed by the arguments defined by `argspec`.
551
+ /// @param argspec The argument specifications for the method.
552
+ /// @return Returns the receiver.
537
553
  template <concepts::ConvertibleFromValue Self = Derived, concepts::ArgSpec... ArgSpec>
538
554
  Derived define_singleton_method(concepts::Identifier auto &&mid,
539
555
  std::invocable<Self, typename ArgSpec::ResultType...> auto &&function,
540
556
  ArgSpec... argspec) const;
557
+
558
+ /// @overload
559
+ ///
560
+ /// This overload defines a method that does not use the receiver.
561
+ ///
562
+ /// @warning Defining a method this way allocates a resource that will never be
563
+ /// garbage-collected.
564
+ ///
565
+ /// @tparam Self Must be `void`.
566
+ /// @param mid The name of the method.
567
+ /// @param function The C++ function to be invoked. It should accept the
568
+ /// arguments defined by `argspec`.
569
+ /// @param argspec The argument specifications for the method.
570
+ /// @return Returns the receiver.
571
+ template <concepts::Void Self, concepts::ArgSpec... ArgSpec>
572
+ Derived define_singleton_method(concepts::Identifier auto &&mid,
573
+ std::invocable<typename ArgSpec::ResultType...> auto &&function,
574
+ ArgSpec... argspec) const;
541
575
  };
542
576
 
543
577
  class Value: public ValueT<Value, ValueBase, Nilable> {
@@ -635,6 +669,23 @@ namespace rcx {
635
669
  std::invocable<Self, typename ArgSpec::ResultType...> auto &&function,
636
670
  ArgSpec... argspec) const;
637
671
 
672
+ /// @overload
673
+ ///
674
+ /// This overload defines a method that does not use the receiver.
675
+ ///
676
+ /// @warning Defining method this way allocates a resource that will never be
677
+ /// garbage-collected.
678
+ ///
679
+ /// @tparam Self Must be `void`.
680
+ /// @param mid The name of the method.
681
+ /// @param function The function to be called.
682
+ /// @param argspec List of argument specifications.
683
+ /// @return Self.
684
+ template <concepts::Void Self, concepts::ArgSpec... ArgSpec>
685
+ Module define_method(concepts::Identifier auto &&mid,
686
+ std::invocable<typename ArgSpec::ResultType...> auto &&function,
687
+ ArgSpec... argspec) const;
688
+
638
689
  /// Checks if a constant is defined under this module.
639
690
  ///
640
691
  /// @param name Name of the constant.
@@ -235,7 +235,7 @@ namespace rcx {
235
235
  std::conditional_t<std::derived_from<T, typed_data::WrappedStructBase>, T const &, T const>;
236
236
  };
237
237
 
238
- namespace arg {
238
+ namespace args {
239
239
  template <concepts::ConvertibleFromValue T>
240
240
  inline typename Self<T>::ResultType Self<T>::parse(Ruby &, Value self, std::span<Value> &) {
241
241
  return from_Value<T>(self);
@@ -611,7 +611,7 @@ namespace rcx {
611
611
  inline Derived ValueT<Derived, Super, nilable>::define_singleton_method(
612
612
  concepts::Identifier auto &&mid,
613
613
  std::invocable<Self, typename ArgSpec::ResultType...> auto &&function, ArgSpec...) const {
614
- auto const callback = detail::method_callback<arg::Self<Self>, ArgSpec...>::alloc(
614
+ auto const callback = detail::method_callback<args::Self<Self>, ArgSpec...>::alloc(
615
615
  std::forward<decltype(function)>(function));
616
616
  detail::protect([&]() noexcept {
617
617
  auto const singleton = ::rb_singleton_class(this->as_VALUE());
@@ -621,6 +621,21 @@ namespace rcx {
621
621
  return *static_cast<Derived const *>(this);
622
622
  }
623
623
 
624
+ template <typename Derived, std::derived_from<ValueBase> Super, Nilability nilable>
625
+ template <concepts::Void, concepts::ArgSpec... ArgSpec>
626
+ inline Derived ValueT<Derived, Super, nilable>::define_singleton_method(
627
+ concepts::Identifier auto &&mid,
628
+ std::invocable<typename ArgSpec::ResultType...> auto &&function, ArgSpec...) const {
629
+ auto const callback =
630
+ detail::method_callback<ArgSpec...>::alloc(std::forward<decltype(function)>(function));
631
+ detail::protect([&]() noexcept {
632
+ auto const singleton = ::rb_singleton_class(this->as_VALUE());
633
+ rb_define_method_id(
634
+ singleton, detail::into_ID(std::forward<decltype(mid)>(mid)), callback, -1);
635
+ });
636
+ return *static_cast<Derived const *>(this);
637
+ }
638
+
624
639
  /// Value
625
640
 
626
641
  template <concepts::ConvertibleFromValue R>
@@ -707,7 +722,18 @@ namespace rcx {
707
722
  template <concepts::ConvertibleFromValue Self, concepts::ArgSpec... ArgSpec>
708
723
  inline Module Module::define_method(concepts::Identifier auto &&mid,
709
724
  std::invocable<Self, typename ArgSpec::ResultType...> auto &&function, ArgSpec...) const {
710
- auto const callback = detail::method_callback<arg::Self<Self>, ArgSpec...>::alloc(function);
725
+ auto const callback = detail::method_callback<args::Self<Self>, ArgSpec...>::alloc(function);
726
+ detail::protect([&]() noexcept {
727
+ rb_define_method_id(
728
+ as_VALUE(), detail::into_ID(std::forward<decltype(mid)>(mid)), callback, -1);
729
+ });
730
+ return *this;
731
+ }
732
+
733
+ template <concepts::Void, concepts::ArgSpec... ArgSpec>
734
+ inline Module Module::define_method(concepts::Identifier auto &&mid,
735
+ std::invocable<typename ArgSpec::ResultType...> auto &&function, ArgSpec...) const {
736
+ auto const callback = detail::method_callback<ArgSpec...>::alloc(function);
711
737
  detail::protect([&]() noexcept {
712
738
  rb_define_method_id(
713
739
  as_VALUE(), detail::into_ID(std::forward<decltype(mid)>(mid)), callback, -1);
@@ -792,7 +818,7 @@ namespace rcx {
792
818
  inline ClassT<T> ClassT<T>::define_method(concepts::Identifier auto &&mid,
793
819
  std::invocable<T &, typename ArgSpec::ResultType...> auto &&function, ArgSpec...) const {
794
820
  auto const callback =
795
- detail::method_callback<arg::Self<detail::self_type<T>>, ArgSpec...>::alloc(
821
+ detail::method_callback<args::Self<detail::self_type<T>>, ArgSpec...>::alloc(
796
822
  std::forward<decltype(function)>(function));
797
823
  detail::protect([&]() noexcept {
798
824
  rb_define_method_id(
@@ -807,7 +833,7 @@ namespace rcx {
807
833
  std::invocable<T const &, typename ArgSpec::ResultType...> auto &&function,
808
834
  ArgSpec...) const {
809
835
  auto const callback =
810
- detail::method_callback<arg::Self<detail::self_type_const<T>>, ArgSpec...>::alloc(
836
+ detail::method_callback<args::Self<detail::self_type_const<T>>, ArgSpec...>::alloc(
811
837
  function);
812
838
  detail::protect([&]() noexcept {
813
839
  rb_define_method_id(
@@ -820,7 +846,7 @@ namespace rcx {
820
846
  template <concepts::ArgSpec... ArgSpec>
821
847
  requires std::constructible_from<T, typename ArgSpec::ResultType...>
822
848
  inline ClassT<T> ClassT<T>::define_constructor(ArgSpec...) const {
823
- auto const callback = detail::method_callback<arg::Self<Value>, ArgSpec...>::alloc(
849
+ auto const callback = detail::method_callback<args::Self<Value>, ArgSpec...>::alloc(
824
850
  typed_data::DataType<T>::template initialize<typename ArgSpec::ResultType...>);
825
851
  detail::protect([&]() noexcept {
826
852
  using namespace literals;
@@ -833,7 +859,7 @@ namespace rcx {
833
859
  inline ClassT<T> ClassT<T>::define_copy_constructor() const
834
860
  requires std::copy_constructible<T>
835
861
  {
836
- auto const callback = detail::method_callback<arg::Self<Value>, arg::Arg<T const &>>::alloc(
862
+ auto const callback = detail::method_callback<args::Self<Value>, args::Arg<T const &>>::alloc(
837
863
  typed_data::DataType<T>::initialize_copy);
838
864
  detail::protect([&]() noexcept {
839
865
  using namespace literals;
data/lib/rcx/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RCX
2
- VERSION = -'0.3.1'
2
+ VERSION = -'0.4.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rcx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kasumi Hanazuki