rcx 0.3.1 → 0.4.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: 4074c5868fd711ee67726acd364d4aa243c5aeaf9fad6232756e9c1fde7539e3
4
- data.tar.gz: e38a49e450466554a5845189cf2ae51ba31665f18389bf9a8d1a052fe6858353
3
+ metadata.gz: ce9f666d5afd1ffe424c7b8e5626537798e7a9dc4f19ab783f9989666ae4e31a
4
+ data.tar.gz: 87e2026fc88693d433d21dddbd337808f1b4ec15f3ffedfb80cb48fa257a7ead
5
5
  SHA512:
6
- metadata.gz: cb13a7ca26f4caf50b3ad8038044f6abf7f932e612e1047df7c54bc543af07a4400a5f68fc64f37406eedff1234de7e99a58583a073c0cf4cbae916c0b03cdd8
7
- data.tar.gz: 918833acbc1d6d1bc2b5c9678533ccd6a8bbdd8f5a6b2b87e18e0baf12443eb3887cb2b8b7ca5349f897e37eb9d0a2c06381e4501870db5e00c25317cc76a9f0
6
+ metadata.gz: d11fcf253149217c95c8f2be3e493607cba542ba9c991f0d55a067198b2e6d5ade3beea98c46a740363b87d91a4f4430b74d58b10c159ba5725ea61d33660bf9
7
+ data.tar.gz: 514a44dab049c8a7d854777f1ce8b8bec7cbc7a08acc322cda5b7d39d43d7f97053e3d7ee52476c8494914cd7ba5e9d8a9317ae9c578843b592ed2cae92d785d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## UNRELEASED
2
2
 
3
+ ## v0.4.1 (2025-09-06)
4
+ - Improved the types of the builtin classes to properly relate to the value wrappers.
5
+
6
+ ## v0.4.0 (2025-09-03)
7
+ - Renamed `rcx::arg` namespace to `rcx::args` to prevent conflit with `rcx::arg::arg`.
8
+
3
9
  ## v0.3.1 (2025-09-02)
4
10
  - Now `extconf.rb`'s can only `require 'rcx/mkmf/c++20'` to enable RCX.
5
11
 
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,13 +67,9 @@ namespace rcx {
67
67
  /// Concepts
68
68
  ///
69
69
  namespace concepts {
70
+ /// Specifies the type `void`.
70
71
  template <typename T>
71
- concept StringLike = requires {
72
- typename std::remove_cvref_t<T>::value_type;
73
- typename std::remove_cvref_t<T>::traits_type;
74
- typename std::basic_string_view<typename std::remove_cvref_t<T>::value_type,
75
- typename std::remove_cvref_t<T>::traits_type>;
76
- };
72
+ concept Void = std::is_void_v<T>;
77
73
 
78
74
  /// Specifies the types that can be used as Ruby identifiers.
79
75
  ///
@@ -286,7 +282,7 @@ namespace rcx {
286
282
  /// Specifies the types that can be converted from Ruby values.
287
283
  ///
288
284
  template <typename T>
289
- concept ConvertibleFromValue = requires(Value v) { from_Value<T>(v); };
285
+ concept ConvertibleFromValue = !std::is_void_v<T> && requires(Value v) { from_Value<T>(v); };
290
286
 
291
287
  /// Specifies the types that can be converted into Ruby values.
292
288
  ///
@@ -316,7 +312,7 @@ namespace rcx {
316
312
 
317
313
  /// Argument parsing.
318
314
  ///
319
- namespace arg {
315
+ namespace args {
320
316
  template <concepts::ConvertibleFromValue T = Value> struct Self {
321
317
  using ResultType = detail::wrap_ref_t<T>;
322
318
  static ResultType parse(Ruby &, Value self, std::span<Value> &args);
@@ -406,6 +402,16 @@ namespace rcx {
406
402
  requires CharTraits<::rcx::CharTraits<std::remove_cvref_t<T>>>;
407
403
  typename std::basic_string_view<std::remove_cvref_t<T>>;
408
404
  };
405
+
406
+ /// Specifies the string types that can be mapped to Ruby strings.
407
+ ///
408
+ template <typename T>
409
+ concept StringLike = requires {
410
+ requires CharLike<typename std::remove_cvref_t<T>::value_type>;
411
+ typename std::remove_cvref_t<T>::traits_type;
412
+ typename std::basic_string_view<typename std::remove_cvref_t<T>::value_type,
413
+ typename std::remove_cvref_t<T>::traits_type>;
414
+ };
409
415
  };
410
416
 
411
417
  /// Literals
@@ -534,10 +540,40 @@ namespace rcx {
534
540
  ClassT<Derived> get_class() const;
535
541
  Derived freeze() const;
536
542
 
543
+ /// Defines a singleton method for the object.
544
+ ///
545
+ /// @warning Defining a method this way allocates a resource that will never be
546
+ /// garbage-collected.
547
+ ///
548
+ /// @tparam Self The type of the receiver.
549
+ /// @tparam ArgSpec The types of the method arguments.
550
+ /// @param mid The name of the method.
551
+ /// @param function The C++ function to be invoked. It should accept `Self` as
552
+ /// the first argument, followed by the arguments defined by `argspec`.
553
+ /// @param argspec The argument specifications for the method.
554
+ /// @return Returns the receiver.
537
555
  template <concepts::ConvertibleFromValue Self = Derived, concepts::ArgSpec... ArgSpec>
538
556
  Derived define_singleton_method(concepts::Identifier auto &&mid,
539
557
  std::invocable<Self, typename ArgSpec::ResultType...> auto &&function,
540
558
  ArgSpec... argspec) const;
559
+
560
+ /// @overload
561
+ ///
562
+ /// This overload defines a method that does not use the receiver.
563
+ ///
564
+ /// @warning Defining a method this way allocates a resource that will never be
565
+ /// garbage-collected.
566
+ ///
567
+ /// @tparam Self Must be `void`.
568
+ /// @param mid The name of the method.
569
+ /// @param function The C++ function to be invoked. It should accept the
570
+ /// arguments defined by `argspec`.
571
+ /// @param argspec The argument specifications for the method.
572
+ /// @return Returns the receiver.
573
+ template <concepts::Void Self, concepts::ArgSpec... ArgSpec>
574
+ Derived define_singleton_method(concepts::Identifier auto &&mid,
575
+ std::invocable<typename ArgSpec::ResultType...> auto &&function,
576
+ ArgSpec... argspec) const;
541
577
  };
542
578
 
543
579
  class Value: public ValueT<Value, ValueBase, Nilable> {
@@ -635,6 +671,23 @@ namespace rcx {
635
671
  std::invocable<Self, typename ArgSpec::ResultType...> auto &&function,
636
672
  ArgSpec... argspec) const;
637
673
 
674
+ /// @overload
675
+ ///
676
+ /// This overload defines a method that does not use the receiver.
677
+ ///
678
+ /// @warning Defining method this way allocates a resource that will never be
679
+ /// garbage-collected.
680
+ ///
681
+ /// @tparam Self Must be `void`.
682
+ /// @param mid The name of the method.
683
+ /// @param function The function to be called.
684
+ /// @param argspec List of argument specifications.
685
+ /// @return Self.
686
+ template <concepts::Void Self, concepts::ArgSpec... ArgSpec>
687
+ Module define_method(concepts::Identifier auto &&mid,
688
+ std::invocable<typename ArgSpec::ResultType...> auto &&function,
689
+ ArgSpec... argspec) const;
690
+
638
691
  /// Checks if a constant is defined under this module.
639
692
  ///
640
693
  /// @param name Name of the constant.
@@ -1101,7 +1154,8 @@ namespace rcx {
1101
1154
  inline value::Class const Encoding = detail::unsafe_coerce<value::Class>(::rb_cEncoding);
1102
1155
  /// `Symbol` class
1103
1156
  ///
1104
- inline value::Class const Symbol = detail::unsafe_coerce<value::Class>(::rb_cSymbol);
1157
+ inline value::ClassT<value::Symbol> const Symbol =
1158
+ detail::unsafe_coerce<value::ClassT<value::Symbol>>(::rb_cSymbol);
1105
1159
  /// `Regexp` class
1106
1160
  ///
1107
1161
  inline value::Class const Regexp = detail::unsafe_coerce<value::Class>(::rb_cRegexp);
@@ -1141,10 +1195,12 @@ namespace rcx {
1141
1195
  inline value::Class const Range = detail::unsafe_coerce<value::Class>(::rb_cRange);
1142
1196
  /// `IO` class
1143
1197
  ///
1144
- inline value::Class const IO = detail::unsafe_coerce<value::Class>(::rb_cIO);
1198
+ inline value::ClassT<value::IO> const IO =
1199
+ detail::unsafe_coerce<value::ClassT<value::IO>>(::rb_cIO);
1145
1200
  /// `File` class
1146
1201
  ///
1147
- inline value::Class const File = detail::unsafe_coerce<value::Class>(::rb_cFile);
1202
+ inline value::ClassT<value::IO> const File =
1203
+ detail::unsafe_coerce<value::ClassT<value::IO>>(::rb_cFile);
1148
1204
  /// `Thread` class
1149
1205
  ///
1150
1206
  inline value::Class const Thread = detail::unsafe_coerce<value::Class>(::rb_cThread);
@@ -1293,7 +1349,8 @@ namespace rcx {
1293
1349
  #ifdef RCX_IO_BUFFER
1294
1350
  /// `IO::Buffer` class
1295
1351
  ///
1296
- inline value::Class const IOBuffer = detail::unsafe_coerce<value::Class>(::rb_cIOBuffer);
1352
+ inline value::ClassT<value::IOBuffer> const IOBuffer =
1353
+ detail::unsafe_coerce<value::ClassT<value::IOBuffer>>(::rb_cIOBuffer);
1297
1354
  #endif
1298
1355
  };
1299
1356
 
@@ -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.1'
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.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kasumi Hanazuki