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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Rakefile +1 -1
- data/examples/class.cpp +1 -1
- data/include/rcx/internal/rcx.hpp +69 -12
- data/include/rcx/internal/rcx_impl.hpp +33 -7
- data/lib/rcx/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce9f666d5afd1ffe424c7b8e5626537798e7a9dc4f19ab783f9989666ae4e31a
|
|
4
|
+
data.tar.gz: 87e2026fc88693d433d21dddbd337808f1b4ec15f3ffedfb80cb48fa257a7ead
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
data/examples/class.cpp
CHANGED
|
@@ -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
|
|
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
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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