ruby-qt6-rice 2.1.0 → 6.0.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 +4 -4
- data/.rubocop.yml +1 -1
- data/Rakefile +12 -1
- data/ext/qt6/rice/extconf.rb +5 -0
- data/ext/qt6/rice/rice-rb.cpp +10 -0
- data/ext/qt6/rice/rice-rb.hpp +3 -0
- data/include/bando/common.hpp +2 -1
- data/include/bando/qobject/qdbusabstractadaptor.hpp +1 -1
- data/include/bando/qobject/qdbusabstractinterface.hpp +1 -1
- data/include/bando/qobject/qitemdelegate.hpp +1 -1
- data/include/bando/qobject/qlayout.hpp +1 -1
- data/include/bando/qobject/qwebenginepage.hpp +1 -1
- data/include/bando/qobject.hpp +1 -1
- data/include/bando/qwidget/qspinbox.hpp +1 -1
- data/include/bando/qwidget.hpp +1 -1
- data/include/rice/core/rice.hpp +1711 -1314
- data/include/rice/core/stl.hpp +562 -82
- data/include/rice/cxx/asserts.hpp +31 -0
- data/include/rice/cxx/concepts.hpp +31 -0
- data/include/rice/qt6/preludes/libqt6core.hpp +192 -0
- data/include/rice/qt6/preludes/libqt6gui.hpp +176 -0
- data/include/rice/qt6/preludes/libqt6multimedia.hpp +33 -0
- data/include/rice/qt6/preludes/libqt6qml.hpp +33 -0
- data/include/rice/qt6/preludes/libqt6quick.hpp +30 -0
- data/include/rice/qt6/preludes/libqt6webenginecore.hpp +30 -0
- data/include/rice/qt6/preludes/libqt6widgets.hpp +35 -0
- data/include/rice/qt6/preludes/qlass.hpp +63 -0
- data/include/rice/qt6/preludes/registries.hpp +52 -0
- data/include/rice/qt6/preludes.hpp +28 -0
- data/include/rice/qt6/qdbusreply.hpp +3 -3
- data/include/rice/qt6/qenum.hpp +1 -1
- data/include/rice/qt6/qflags.hpp +1 -1
- data/include/rice/qt6/qlist.hpp +17 -20
- data/include/rice/qt6/qmap.hpp +14 -11
- data/include/rice/qt6.hpp +3 -0
- data/lib/mkmf-rubyqt6.rb +24 -7
- data/lib/qt6/rice/version.rb +1 -1
- data/lib/qt6/rice.rb +1 -0
- metadata +18 -2
data/include/rice/core/rice.hpp
CHANGED
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
|
54
54
|
#endif
|
|
55
55
|
|
|
56
|
+
#include <ruby/version.h>
|
|
56
57
|
#include <ruby.h>
|
|
57
58
|
#include <ruby/encoding.h>
|
|
58
59
|
#include <ruby/thread.h>
|
|
@@ -89,23 +90,6 @@ extern "C" typedef VALUE (*RUBY_VALUE_FUNC)(VALUE);
|
|
|
89
90
|
extern "C" typedef VALUE (*RUBY_METHOD_FUNC)(ANYARGS);
|
|
90
91
|
#endif
|
|
91
92
|
|
|
92
|
-
// This is a terrible hack for Ruby 3.1 and maybe earlier to avoid crashes when test_Attribute unit cases
|
|
93
|
-
// are run. If ruby_options is called to initialize the interpeter (previously it was not), when
|
|
94
|
-
// the attribute unit tests intentionally cause exceptions to happen, the exception is correctly processed.
|
|
95
|
-
// However any calls back to Ruby, for example to get the exception message, crash because the ruby
|
|
96
|
-
// execution context tag has been set to null. This does not happen in newer versions of Ruby. It is
|
|
97
|
-
// unknown if this happens in real life or just the test caes.
|
|
98
|
-
// Should be removed when Rice no longer supports Ruby 3.1
|
|
99
|
-
#if RUBY_API_VERSION_MAJOR == 3 && RUBY_API_VERSION_MINOR < 2
|
|
100
|
-
constexpr bool oldRuby = true;
|
|
101
|
-
#elif RUBY_API_VERSION_MAJOR < 3
|
|
102
|
-
constexpr bool oldRuby = true;
|
|
103
|
-
#else
|
|
104
|
-
constexpr bool oldRuby = false;
|
|
105
|
-
#endif
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
93
|
|
|
110
94
|
|
|
111
95
|
// C++ headers have to come after Ruby on MacOS for reasons I do not understand
|
|
@@ -125,6 +109,7 @@ extern "C" typedef VALUE (*RUBY_VALUE_FUNC)(VALUE);
|
|
|
125
109
|
|
|
126
110
|
// ========= rice_traits.hpp =========
|
|
127
111
|
|
|
112
|
+
#include <complex>
|
|
128
113
|
#include <ostream>
|
|
129
114
|
#include <tuple>
|
|
130
115
|
#include <type_traits>
|
|
@@ -237,6 +222,15 @@ namespace Rice4RubyQt6
|
|
|
237
222
|
template <typename T>
|
|
238
223
|
constexpr bool is_std_vector_v = is_std_vector<T>::value;
|
|
239
224
|
|
|
225
|
+
template<typename>
|
|
226
|
+
struct is_std_complex : std::false_type {};
|
|
227
|
+
|
|
228
|
+
template<typename T>
|
|
229
|
+
struct is_std_complex<std::complex<T>> : std::true_type {};
|
|
230
|
+
|
|
231
|
+
template <typename T>
|
|
232
|
+
constexpr bool is_std_complex_v = is_std_complex<T>::value;
|
|
233
|
+
|
|
240
234
|
template<class T>
|
|
241
235
|
struct is_pointer_pointer : std::false_type {};
|
|
242
236
|
|
|
@@ -265,17 +259,39 @@ namespace Rice4RubyQt6
|
|
|
265
259
|
}, std::forward<Tuple_T>(tuple));
|
|
266
260
|
}
|
|
267
261
|
|
|
262
|
+
// Detect if a type is complete (has a known size) or incomplete (forward-declared only)
|
|
263
|
+
template<typename T, typename = void>
|
|
264
|
+
struct is_complete : std::false_type {};
|
|
265
|
+
|
|
266
|
+
template<typename T>
|
|
267
|
+
struct is_complete<T, std::void_t<decltype(sizeof(T))>> : std::true_type {};
|
|
268
|
+
|
|
269
|
+
template<typename T>
|
|
270
|
+
constexpr bool is_complete_v = is_complete<T>::value;
|
|
271
|
+
|
|
268
272
|
template<typename T, typename = void>
|
|
269
273
|
struct is_wrapped : std::true_type {};
|
|
270
274
|
|
|
271
275
|
template<typename T>
|
|
272
276
|
struct is_wrapped<T, std::enable_if_t<std::is_fundamental_v<detail::intrinsic_type<T>> ||
|
|
273
|
-
std::is_same_v<detail::intrinsic_type<T>, std::string
|
|
277
|
+
std::is_same_v<detail::intrinsic_type<T>, std::string> ||
|
|
278
|
+
is_std_complex_v<T>>
|
|
274
279
|
>: std::false_type {};
|
|
275
280
|
|
|
276
281
|
template<typename T>
|
|
277
282
|
constexpr bool is_wrapped_v = is_wrapped<T>::value;
|
|
278
283
|
|
|
284
|
+
// ---------- RubyKlass ------------
|
|
285
|
+
template<typename, typename = std::void_t<>>
|
|
286
|
+
struct has_ruby_klass : std::false_type
|
|
287
|
+
{
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
template<typename T>
|
|
291
|
+
struct has_ruby_klass<T, std::void_t<decltype(T::rubyKlass())>> : std::true_type
|
|
292
|
+
{
|
|
293
|
+
};
|
|
294
|
+
|
|
279
295
|
// -- Tuple Helpers ---
|
|
280
296
|
template<typename T>
|
|
281
297
|
struct tuple_shift;
|
|
@@ -474,14 +490,29 @@ namespace Rice4RubyQt6::detail
|
|
|
474
490
|
using class_type = std::nullptr_t;
|
|
475
491
|
};
|
|
476
492
|
|
|
493
|
+
// Lvalue references to functors and lambdas - strip the reference and defer
|
|
494
|
+
// to the base functor specialization. This allows named lambda variables (lvalues)
|
|
495
|
+
// to be passed to define_method in addition to inline temporaries (rvalues).
|
|
496
|
+
template<typename Function_T>
|
|
497
|
+
struct function_traits<Function_T&> : public function_traits<Function_T>
|
|
498
|
+
{
|
|
499
|
+
};
|
|
500
|
+
|
|
477
501
|
// C functions and static member functions passed by pointer
|
|
478
502
|
template<typename Return_T, typename ...Parameter_Ts>
|
|
479
503
|
struct function_traits<Return_T(*)(Parameter_Ts...)> : public function_traits<Return_T(std::nullptr_t, Parameter_Ts...)>
|
|
480
504
|
{
|
|
481
505
|
using Function_T = Return_T(*)(Parameter_Ts...);
|
|
482
506
|
};
|
|
483
|
-
|
|
484
|
-
// C functions
|
|
507
|
+
|
|
508
|
+
// noexcept C functions and static member functions passed by pointer
|
|
509
|
+
template<typename Return_T, typename ...Parameter_Ts>
|
|
510
|
+
struct function_traits<Return_T(*)(Parameter_Ts...) noexcept> : public function_traits<Return_T(std::nullptr_t, Parameter_Ts...)>
|
|
511
|
+
{
|
|
512
|
+
using Function_T = Return_T(*)(Parameter_Ts...) noexcept;
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
// C functions passed by pointer that take one or more defined parameter than a variable
|
|
485
516
|
// number of parameters (the second ...)
|
|
486
517
|
template<typename Return_T, typename ...Parameter_Ts>
|
|
487
518
|
struct function_traits<Return_T(*)(Parameter_Ts..., ...)> : public function_traits<Return_T(std::nullptr_t, Parameter_Ts...)>
|
|
@@ -494,6 +525,12 @@ namespace Rice4RubyQt6::detail
|
|
|
494
525
|
{
|
|
495
526
|
};
|
|
496
527
|
|
|
528
|
+
// noexcept C functions or static member functions passed by reference
|
|
529
|
+
template<typename Return_T, typename ...Parameter_Ts>
|
|
530
|
+
struct function_traits<Return_T(&)(Parameter_Ts...) noexcept> : public function_traits<Return_T(std::nullptr_t, Parameter_Ts...)>
|
|
531
|
+
{
|
|
532
|
+
};
|
|
533
|
+
|
|
497
534
|
// Member Functions on C++ classes
|
|
498
535
|
template<typename Return_T, typename Class_T, typename...Parameter_Ts>
|
|
499
536
|
struct function_traits<Return_T(Class_T::*)(Parameter_Ts...)> : public function_traits<Return_T(Class_T*, Parameter_Ts...)>
|
|
@@ -611,6 +648,8 @@ namespace Rice4RubyQt6::detail
|
|
|
611
648
|
|
|
612
649
|
void ruby_mark();
|
|
613
650
|
void addKeepAlive(VALUE value);
|
|
651
|
+
const std::vector<VALUE>& getKeepAlive() const;
|
|
652
|
+
void setKeepAlive(const std::vector<VALUE>& keepAlive);
|
|
614
653
|
void setOwner(bool value);
|
|
615
654
|
|
|
616
655
|
protected:
|
|
@@ -631,7 +670,7 @@ namespace Rice4RubyQt6::detail
|
|
|
631
670
|
public:
|
|
632
671
|
Wrapper(rb_data_type_t* rb_data_type, T& data);
|
|
633
672
|
Wrapper(rb_data_type_t* rb_data_type, T&& data);
|
|
634
|
-
~Wrapper();
|
|
673
|
+
~Wrapper() = default;
|
|
635
674
|
void* get(rb_data_type_t* requestedType) override;
|
|
636
675
|
|
|
637
676
|
private:
|
|
@@ -676,7 +715,7 @@ namespace Rice4RubyQt6::detail
|
|
|
676
715
|
|
|
677
716
|
// ---- Helper Functions ---------
|
|
678
717
|
template <typename T>
|
|
679
|
-
Wrapper<T*>* wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data);
|
|
718
|
+
Wrapper<T*>* wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data, VALUE source = Qnil);
|
|
680
719
|
|
|
681
720
|
template <typename T>
|
|
682
721
|
VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner);
|
|
@@ -693,9 +732,8 @@ namespace Rice4RubyQt6::detail
|
|
|
693
732
|
WrapperBase* getWrapper(VALUE value);
|
|
694
733
|
}
|
|
695
734
|
|
|
696
|
-
// ========= Type.hpp =========
|
|
697
735
|
|
|
698
|
-
|
|
736
|
+
// ========= Type.hpp =========
|
|
699
737
|
|
|
700
738
|
namespace Rice4RubyQt6::detail
|
|
701
739
|
{
|
|
@@ -729,6 +767,28 @@ namespace Rice4RubyQt6::detail
|
|
|
729
767
|
static bool verify();
|
|
730
768
|
};
|
|
731
769
|
|
|
770
|
+
template <typename T, int N>
|
|
771
|
+
struct Type<T[N]>
|
|
772
|
+
{
|
|
773
|
+
static bool verify();
|
|
774
|
+
static VALUE rubyKlass();
|
|
775
|
+
};
|
|
776
|
+
|
|
777
|
+
template<typename T>
|
|
778
|
+
void verifyType();
|
|
779
|
+
|
|
780
|
+
template<typename Tuple_T>
|
|
781
|
+
void verifyTypes();
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
// ========= TypeIndexParser.hpp =========
|
|
786
|
+
|
|
787
|
+
#include <regex>
|
|
788
|
+
#include <typeindex>
|
|
789
|
+
|
|
790
|
+
namespace Rice4RubyQt6::detail
|
|
791
|
+
{
|
|
732
792
|
class TypeIndexParser
|
|
733
793
|
{
|
|
734
794
|
public:
|
|
@@ -740,39 +800,131 @@ namespace Rice4RubyQt6::detail
|
|
|
740
800
|
// public only for testing
|
|
741
801
|
std::string findGroup(std::string& string, size_t start = 0);
|
|
742
802
|
|
|
743
|
-
|
|
803
|
+
protected:
|
|
744
804
|
std::string demangle(char const* mangled_name);
|
|
745
805
|
void removeGroup(std::string& string, std::regex regex);
|
|
746
806
|
void replaceGroup(std::string& string, std::regex regex, std::string replacement);
|
|
747
807
|
void capitalizeHelper(std::string& content, std::regex& regex);
|
|
748
808
|
void replaceAll(std::string& string, std::regex regex, std::string replacement);
|
|
749
809
|
|
|
750
|
-
|
|
810
|
+
protected:
|
|
751
811
|
const std::type_index typeIndex_;
|
|
752
812
|
bool isFundamental_ = false;
|
|
753
813
|
};
|
|
754
814
|
|
|
755
815
|
template<typename T>
|
|
756
|
-
class
|
|
816
|
+
class TypeDetail
|
|
757
817
|
{
|
|
758
818
|
public:
|
|
819
|
+
std::string name();
|
|
820
|
+
std::string simplifiedName();
|
|
821
|
+
|
|
759
822
|
VALUE rubyKlass();
|
|
760
823
|
std::string rubyName();
|
|
761
824
|
|
|
762
825
|
private:
|
|
826
|
+
static std::type_index typeIndex();
|
|
827
|
+
static bool isFundamental();
|
|
763
828
|
std::string rubyTypeName();
|
|
764
|
-
|
|
829
|
+
|
|
765
830
|
private:
|
|
766
|
-
TypeIndexParser typeIndexParser_{
|
|
831
|
+
TypeIndexParser typeIndexParser_{ typeIndex(), isFundamental() };
|
|
767
832
|
};
|
|
833
|
+
}
|
|
768
834
|
|
|
769
|
-
template<typename T>
|
|
770
|
-
void verifyType();
|
|
771
835
|
|
|
772
|
-
|
|
773
|
-
|
|
836
|
+
// Code to register Ruby objects with GC (declarations)
|
|
837
|
+
|
|
838
|
+
// ========= Anchor.hpp =========
|
|
839
|
+
|
|
840
|
+
#include <ruby.h>
|
|
841
|
+
|
|
842
|
+
namespace Rice4RubyQt6
|
|
843
|
+
{
|
|
844
|
+
namespace detail
|
|
845
|
+
{
|
|
846
|
+
//! Internal GC anchor for a Ruby VALUE.
|
|
847
|
+
/*!
|
|
848
|
+
* Anchor is a low-level adapter around the Ruby GC API.
|
|
849
|
+
* It owns a stable VALUE slot whose address is registered
|
|
850
|
+
* with the Ruby garbage collector.
|
|
851
|
+
*
|
|
852
|
+
* This class encapsulates all GC registration logic and is
|
|
853
|
+
* not part of the public Rice API.
|
|
854
|
+
*/
|
|
855
|
+
class Anchor
|
|
856
|
+
{
|
|
857
|
+
public:
|
|
858
|
+
//! Construct an anchor for the given Ruby VALUE.
|
|
859
|
+
/*!
|
|
860
|
+
* The address of the internal VALUE is registered with the
|
|
861
|
+
* Ruby GC, preventing collection while this Anchor exists.
|
|
862
|
+
*/
|
|
863
|
+
explicit Anchor(VALUE value);
|
|
864
|
+
|
|
865
|
+
//! Unregister the VALUE from the Ruby GC.
|
|
866
|
+
~Anchor();
|
|
867
|
+
|
|
868
|
+
Anchor(const Anchor&) = delete;
|
|
869
|
+
Anchor& operator=(const Anchor&) = delete;
|
|
870
|
+
|
|
871
|
+
//! Retrieve the currently anchored VALUE.
|
|
872
|
+
VALUE get() const;
|
|
873
|
+
|
|
874
|
+
private:
|
|
875
|
+
static void disable(VALUE);
|
|
876
|
+
static void registerExitHandler();
|
|
877
|
+
|
|
878
|
+
inline static bool enabled_ = true;
|
|
879
|
+
inline static bool exitHandlerRegistered_ = false;
|
|
880
|
+
|
|
881
|
+
private:
|
|
882
|
+
bool registered_ = false;
|
|
883
|
+
|
|
884
|
+
//! GC-visible Ruby VALUE slot.
|
|
885
|
+
VALUE value_ = Qnil;
|
|
886
|
+
};
|
|
887
|
+
}
|
|
774
888
|
}
|
|
775
889
|
|
|
890
|
+
// ========= Pin.hpp =========
|
|
891
|
+
|
|
892
|
+
namespace Rice4RubyQt6
|
|
893
|
+
{
|
|
894
|
+
//! Strong lifetime policy for a Ruby VALUE.
|
|
895
|
+
/*!
|
|
896
|
+
* Pin represents a Ruby VALUE whose lifetime is explicitly
|
|
897
|
+
* extended by C++ code.
|
|
898
|
+
*
|
|
899
|
+
* Internally, Pin uses a GC Anchor to keep the VALUE alive.
|
|
900
|
+
* Copying a Pin shares the underlying anchor; moving is cheap.
|
|
901
|
+
*
|
|
902
|
+
* This type is intended for C++-owned objects that store Ruby
|
|
903
|
+
* values but are not themselves owned by Ruby and thus do not
|
|
904
|
+
* participate in the GC via a mark function.
|
|
905
|
+
*/
|
|
906
|
+
class Pin
|
|
907
|
+
{
|
|
908
|
+
public:
|
|
909
|
+
//! Construct a pin from a Ruby VALUE.
|
|
910
|
+
Pin(VALUE value);
|
|
911
|
+
|
|
912
|
+
// Copying
|
|
913
|
+
Pin(const Pin&) = default;
|
|
914
|
+
Pin& operator=(const Pin&) = default;
|
|
915
|
+
|
|
916
|
+
// Moving
|
|
917
|
+
Pin(Pin&&) noexcept = default;
|
|
918
|
+
Pin& operator=(Pin&&) noexcept = default;
|
|
919
|
+
|
|
920
|
+
//! Retrieve the pinned Ruby VALUE.
|
|
921
|
+
VALUE value() const;
|
|
922
|
+
|
|
923
|
+
private:
|
|
924
|
+
//! Shared ownership of the internal GC anchor.
|
|
925
|
+
std::shared_ptr<detail::Anchor> anchor_;
|
|
926
|
+
};
|
|
927
|
+
}
|
|
776
928
|
|
|
777
929
|
// Code for C++ to call Ruby
|
|
778
930
|
|
|
@@ -835,8 +987,7 @@ namespace Rice4RubyQt6
|
|
|
835
987
|
VALUE value() const;
|
|
836
988
|
|
|
837
989
|
private:
|
|
838
|
-
|
|
839
|
-
mutable VALUE exception_ = Qnil;
|
|
990
|
+
Pin exception_ = Qnil;
|
|
840
991
|
mutable std::string message_;
|
|
841
992
|
};
|
|
842
993
|
} // namespace Rice4RubyQt6
|
|
@@ -1324,12 +1475,6 @@ namespace Rice4RubyQt6
|
|
|
1324
1475
|
//! Returns if the argument should be treated as a value
|
|
1325
1476
|
bool isValue() const;
|
|
1326
1477
|
|
|
1327
|
-
//! Specifies if the argument should capture a block
|
|
1328
|
-
virtual Arg& setBlock();
|
|
1329
|
-
|
|
1330
|
-
//! Returns if the argument should capture a block
|
|
1331
|
-
bool isBlock() const;
|
|
1332
|
-
|
|
1333
1478
|
//! Specifies if the argument is opaque and Rice should not convert it from Ruby to C++ or vice versa.
|
|
1334
1479
|
//! This is useful for callbacks and user provided data paramameters.
|
|
1335
1480
|
virtual Arg& setOpaque();
|
|
@@ -1348,7 +1493,6 @@ namespace Rice4RubyQt6
|
|
|
1348
1493
|
//! Our saved default value
|
|
1349
1494
|
std::any defaultValue_;
|
|
1350
1495
|
bool isValue_ = false;
|
|
1351
|
-
bool isBlock_ = false;
|
|
1352
1496
|
bool isKeepAlive_ = false;
|
|
1353
1497
|
bool isOwner_ = false;
|
|
1354
1498
|
bool isOpaque_ = false;
|
|
@@ -1358,6 +1502,7 @@ namespace Rice4RubyQt6
|
|
|
1358
1502
|
{
|
|
1359
1503
|
public:
|
|
1360
1504
|
ArgBuffer(std::string name);
|
|
1505
|
+
using Arg::operator=; // Inherit the templated operator=
|
|
1361
1506
|
};
|
|
1362
1507
|
} // Rice
|
|
1363
1508
|
|
|
@@ -1494,6 +1639,78 @@ namespace Rice4RubyQt6::detail
|
|
|
1494
1639
|
};
|
|
1495
1640
|
}
|
|
1496
1641
|
|
|
1642
|
+
// Code to register Ruby objects with GC (implementations)
|
|
1643
|
+
|
|
1644
|
+
// ========= Anchor.ipp =========
|
|
1645
|
+
namespace Rice4RubyQt6
|
|
1646
|
+
{
|
|
1647
|
+
namespace detail
|
|
1648
|
+
{
|
|
1649
|
+
inline Anchor::Anchor(VALUE value) : value_(value)
|
|
1650
|
+
{
|
|
1651
|
+
if (!RB_SPECIAL_CONST_P(value))
|
|
1652
|
+
{
|
|
1653
|
+
Anchor::registerExitHandler();
|
|
1654
|
+
detail::protect(rb_gc_register_address, &this->value_);
|
|
1655
|
+
this->registered_ = true;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
inline Anchor::~Anchor()
|
|
1660
|
+
{
|
|
1661
|
+
if (Anchor::enabled_ && this->registered_)
|
|
1662
|
+
{
|
|
1663
|
+
detail::protect(rb_gc_unregister_address, &this->value_);
|
|
1664
|
+
}
|
|
1665
|
+
// Ruby auto detects VALUEs in the stack, so make sure up in case this object is on the stack
|
|
1666
|
+
this->registered_ = false;
|
|
1667
|
+
this->value_ = Qnil;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
inline VALUE Anchor::get() const
|
|
1671
|
+
{
|
|
1672
|
+
return this->value_;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
// This will be called by ruby at exit - we want to disable further unregistering
|
|
1676
|
+
inline void Anchor::disable(VALUE)
|
|
1677
|
+
{
|
|
1678
|
+
Anchor::enabled_ = false;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
inline void Anchor::registerExitHandler()
|
|
1682
|
+
{
|
|
1683
|
+
if (!Anchor::exitHandlerRegistered_)
|
|
1684
|
+
{
|
|
1685
|
+
detail::protect(rb_set_end_proc, &Anchor::disable, Qnil);
|
|
1686
|
+
Anchor::exitHandlerRegistered_ = true;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
// ========= Pin.ipp =========
|
|
1693
|
+
namespace Rice4RubyQt6
|
|
1694
|
+
{
|
|
1695
|
+
inline Pin::Pin(VALUE value)
|
|
1696
|
+
: anchor_(std::make_shared<detail::Anchor>(value))
|
|
1697
|
+
{
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
inline VALUE Pin::value() const
|
|
1701
|
+
{
|
|
1702
|
+
// Anchor can be nil after a move
|
|
1703
|
+
if (this->anchor_)
|
|
1704
|
+
{
|
|
1705
|
+
return this->anchor_->get();
|
|
1706
|
+
}
|
|
1707
|
+
else
|
|
1708
|
+
{
|
|
1709
|
+
return Qnil;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1497
1714
|
// C++ API declarations
|
|
1498
1715
|
|
|
1499
1716
|
// ========= Encoding.hpp =========
|
|
@@ -1625,41 +1842,36 @@ namespace Rice4RubyQt6
|
|
|
1625
1842
|
class Object
|
|
1626
1843
|
{
|
|
1627
1844
|
public:
|
|
1845
|
+
//! Construct an empty Object wrapper.
|
|
1846
|
+
Object();
|
|
1847
|
+
|
|
1628
1848
|
//! Encapsulate an existing ruby object.
|
|
1629
|
-
Object(VALUE value
|
|
1849
|
+
Object(VALUE value);
|
|
1630
1850
|
|
|
1631
1851
|
//! Destructor
|
|
1632
|
-
virtual ~Object();
|
|
1852
|
+
virtual ~Object() = default;
|
|
1633
1853
|
|
|
1634
1854
|
// Enable copying
|
|
1635
1855
|
Object(const Object& other) = default;
|
|
1636
1856
|
Object& operator=(const Object& other) = default;
|
|
1637
1857
|
|
|
1638
1858
|
// Enable moving
|
|
1639
|
-
Object(Object&& other);
|
|
1640
|
-
Object& operator=(Object&& other);
|
|
1859
|
+
Object(Object&& other) = default;
|
|
1860
|
+
Object& operator=(Object&& other) = default;
|
|
1641
1861
|
|
|
1642
|
-
//!
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
bool test() const { return RTEST(value_); }
|
|
1862
|
+
//! Implicit conversion to VALUE.
|
|
1863
|
+
operator VALUE() const;
|
|
1864
|
+
|
|
1865
|
+
//! Explicitly get the encapsulated VALUE.
|
|
1866
|
+
VALUE value() const;
|
|
1648
1867
|
|
|
1649
1868
|
//! Returns false if the object is nil or false; returns true
|
|
1650
1869
|
//! otherwise.
|
|
1651
|
-
operator bool() const
|
|
1870
|
+
explicit operator bool() const;
|
|
1652
1871
|
|
|
1653
1872
|
//! Returns true if the object is nil, false otherwise.
|
|
1654
|
-
bool is_nil() const
|
|
1873
|
+
bool is_nil() const;
|
|
1655
1874
|
|
|
1656
|
-
//! Implicit conversion to VALUE.
|
|
1657
|
-
operator VALUE() const { return value_; }
|
|
1658
|
-
|
|
1659
|
-
//! Explicitly get the encapsulated VALUE.
|
|
1660
|
-
// Returns a const ref so that Address_Registration_Guard can access
|
|
1661
|
-
// the address where the VALUE is stored
|
|
1662
|
-
VALUE const volatile& value() const { return value_; }
|
|
1663
1875
|
|
|
1664
1876
|
//! Get the class of an object.
|
|
1665
1877
|
/*! \return the object's Class.
|
|
@@ -1860,11 +2072,15 @@ namespace Rice4RubyQt6
|
|
|
1860
2072
|
void remove_const(Identifier name);
|
|
1861
2073
|
|
|
1862
2074
|
protected:
|
|
2075
|
+
//! Checks the encapsulated VALUE is not nil and returns it. If it is nil
|
|
2076
|
+
//! an exception is thrown.
|
|
2077
|
+
VALUE validated_value() const;
|
|
2078
|
+
|
|
1863
2079
|
//! Set the encapsulated value.
|
|
1864
|
-
void set_value(VALUE
|
|
2080
|
+
void set_value(VALUE value);
|
|
1865
2081
|
|
|
1866
2082
|
private:
|
|
1867
|
-
|
|
2083
|
+
Pin value_;
|
|
1868
2084
|
};
|
|
1869
2085
|
|
|
1870
2086
|
std::ostream& operator<<(std::ostream& out, Object const& obj);
|
|
@@ -1873,42 +2089,7 @@ namespace Rice4RubyQt6
|
|
|
1873
2089
|
bool operator!=(Object const& lhs, Object const& rhs);
|
|
1874
2090
|
bool operator<(Object const& lhs, Object const& rhs);
|
|
1875
2091
|
bool operator>(Object const& lhs, Object const& rhs);
|
|
1876
|
-
|
|
1877
|
-
extern Object const Nil;
|
|
1878
|
-
extern Object const True;
|
|
1879
|
-
extern Object const False;
|
|
1880
|
-
extern Object const Undef;
|
|
1881
|
-
} // namespace Rice4RubyQt6
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
// ========= Builtin_Object.hpp =========
|
|
1885
|
-
|
|
1886
|
-
namespace Rice4RubyQt6
|
|
1887
|
-
{
|
|
1888
|
-
//! A smartpointer-like wrapper for Ruby builtin objects.
|
|
1889
|
-
/*! A builtin object is one of Ruby's internal types, e.g. RArray or
|
|
1890
|
-
* RString. Every builtin type structure has a corresponding integer
|
|
1891
|
-
* type number (e.g T_ARRAY for RArray or T_STRING for RString). This
|
|
1892
|
-
* class is a wrapper for those types of objects, primarily useful as a
|
|
1893
|
-
* base class for other wrapper classes like Array and Hash.
|
|
1894
|
-
*/
|
|
1895
|
-
template<int Builtin_Type>
|
|
1896
|
-
class Builtin_Object
|
|
1897
|
-
: public Object
|
|
1898
|
-
{
|
|
1899
|
-
public:
|
|
1900
|
-
//! Wrap an already allocated Ruby object.
|
|
1901
|
-
/*! Checks to see if the object is an object of type Builtin_Type; a
|
|
1902
|
-
* C++ exception is thrown if this is not the case.
|
|
1903
|
-
* \param value the object to be wrapped.
|
|
1904
|
-
*/
|
|
1905
|
-
Builtin_Object(Object value);
|
|
1906
|
-
|
|
1907
|
-
RObject& operator*() const; //!< Return a reference to obj_
|
|
1908
|
-
RObject* operator->() const; //!< Return a pointer to obj_
|
|
1909
|
-
RObject* get() const; //!< Return a pointer to obj_
|
|
1910
|
-
};
|
|
1911
|
-
} // namespace Rice4RubyQt6
|
|
2092
|
+
}
|
|
1912
2093
|
|
|
1913
2094
|
|
|
1914
2095
|
// ========= String.hpp =========
|
|
@@ -1925,7 +2106,7 @@ namespace Rice4RubyQt6
|
|
|
1925
2106
|
* std::cout << s.length() << std::endl;
|
|
1926
2107
|
* \endcode
|
|
1927
2108
|
*/
|
|
1928
|
-
class String : public
|
|
2109
|
+
class String : public Object
|
|
1929
2110
|
{
|
|
1930
2111
|
public:
|
|
1931
2112
|
//! Construct a new string.
|
|
@@ -2046,7 +2227,7 @@ namespace Rice4RubyQt6
|
|
|
2046
2227
|
* \endcode
|
|
2047
2228
|
*/
|
|
2048
2229
|
class Array
|
|
2049
|
-
: public
|
|
2230
|
+
: public Object
|
|
2050
2231
|
{
|
|
2051
2232
|
public:
|
|
2052
2233
|
//! Construct a new array
|
|
@@ -2184,8 +2365,8 @@ namespace Rice4RubyQt6
|
|
|
2184
2365
|
//! Construct a new Proxy
|
|
2185
2366
|
Proxy(Array array, long index);
|
|
2186
2367
|
|
|
2187
|
-
//! Implicit
|
|
2188
|
-
operator
|
|
2368
|
+
//! Implicit conversion to VALUE.
|
|
2369
|
+
operator VALUE() const;
|
|
2189
2370
|
|
|
2190
2371
|
//! Explicit conversion to VALUE.
|
|
2191
2372
|
VALUE value() const;
|
|
@@ -2290,7 +2471,7 @@ namespace Rice4RubyQt6
|
|
|
2290
2471
|
//! h[10] = String("bar");
|
|
2291
2472
|
//! std::cout << String(h[42]) << std::endl;
|
|
2292
2473
|
//! \endcode
|
|
2293
|
-
class Hash: public
|
|
2474
|
+
class Hash: public Object
|
|
2294
2475
|
{
|
|
2295
2476
|
public:
|
|
2296
2477
|
//! Construct a new hash.
|
|
@@ -2367,8 +2548,8 @@ namespace Rice4RubyQt6
|
|
|
2367
2548
|
//! Construct a new Proxy.
|
|
2368
2549
|
Proxy(Hash* hash, Object key);
|
|
2369
2550
|
|
|
2370
|
-
//! Implicit conversion to
|
|
2371
|
-
operator
|
|
2551
|
+
//! Implicit conversion to VALUE.
|
|
2552
|
+
operator VALUE() const;
|
|
2372
2553
|
|
|
2373
2554
|
//! Explicit conversion to VALUE.
|
|
2374
2555
|
VALUE value() const;
|
|
@@ -2466,7 +2647,6 @@ namespace Rice4RubyQt6
|
|
|
2466
2647
|
|
|
2467
2648
|
|
|
2468
2649
|
|
|
2469
|
-
|
|
2470
2650
|
// ========= Module.hpp =========
|
|
2471
2651
|
|
|
2472
2652
|
namespace Rice4RubyQt6
|
|
@@ -2481,18 +2661,17 @@ namespace Rice4RubyQt6
|
|
|
2481
2661
|
* Many of the methods are defined in Module_impl.hpp so that they can
|
|
2482
2662
|
* return a reference to the most derived type.
|
|
2483
2663
|
*/
|
|
2484
|
-
//
|
|
2485
|
-
// type T_CLASS and Module needs type T_MODULE
|
|
2664
|
+
// Module and Class both derive from Object to preserve Ruby's hierarchy.
|
|
2486
2665
|
class Module : public Object
|
|
2487
2666
|
{
|
|
2488
2667
|
public:
|
|
2489
|
-
//! Default construct
|
|
2490
|
-
Module();
|
|
2668
|
+
//! Default construct an empty Module wrapper.
|
|
2669
|
+
Module() = default;
|
|
2491
2670
|
|
|
2492
2671
|
//! Construct a Module from an existing Module object.
|
|
2493
2672
|
Module(VALUE v);
|
|
2494
2673
|
|
|
2495
|
-
//! Construct a Module from
|
|
2674
|
+
//! Construct a Module from a string that references a Module
|
|
2496
2675
|
Module(std::string name, Object under = rb_cObject);
|
|
2497
2676
|
|
|
2498
2677
|
//! Return the name of the module.
|
|
@@ -2526,7 +2705,7 @@ namespace Rice4RubyQt6
|
|
|
2526
2705
|
*/
|
|
2527
2706
|
inline auto& include_module(Module const& inc)
|
|
2528
2707
|
{
|
|
2529
|
-
detail::protect(rb_include_module, this->
|
|
2708
|
+
detail::protect(rb_include_module, this->validated_value(), inc.value());
|
|
2530
2709
|
return *this;
|
|
2531
2710
|
}
|
|
2532
2711
|
|
|
@@ -2550,7 +2729,7 @@ inline auto& include_module(Module const& inc)
|
|
|
2550
2729
|
template<typename Method_T, typename...Arg_Ts>
|
|
2551
2730
|
inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
|
|
2552
2731
|
{
|
|
2553
|
-
this->wrap_native_method(this->
|
|
2732
|
+
this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
|
|
2554
2733
|
return *this;
|
|
2555
2734
|
}
|
|
2556
2735
|
|
|
@@ -2568,7 +2747,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
|
|
|
2568
2747
|
template<typename Function_T, typename...Arg_Ts>
|
|
2569
2748
|
inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
|
|
2570
2749
|
{
|
|
2571
|
-
this->wrap_native_function(this->
|
|
2750
|
+
this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
|
|
2572
2751
|
return *this;
|
|
2573
2752
|
}
|
|
2574
2753
|
|
|
@@ -2642,7 +2821,7 @@ template<typename Constant_T>
|
|
|
2642
2821
|
inline auto& define_constant(std::string name, Constant_T value)
|
|
2643
2822
|
{
|
|
2644
2823
|
using Base_T = detail::remove_cv_recursive_t<Constant_T>;
|
|
2645
|
-
detail::protect(rb_define_const, this->
|
|
2824
|
+
detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
|
|
2646
2825
|
return *this;
|
|
2647
2826
|
}
|
|
2648
2827
|
protected:
|
|
@@ -2724,7 +2903,7 @@ namespace Rice4RubyQt6
|
|
|
2724
2903
|
*/
|
|
2725
2904
|
inline auto& include_module(Module const& inc)
|
|
2726
2905
|
{
|
|
2727
|
-
detail::protect(rb_include_module, this->
|
|
2906
|
+
detail::protect(rb_include_module, this->validated_value(), inc.value());
|
|
2728
2907
|
return *this;
|
|
2729
2908
|
}
|
|
2730
2909
|
|
|
@@ -2748,7 +2927,7 @@ inline auto& include_module(Module const& inc)
|
|
|
2748
2927
|
template<typename Method_T, typename...Arg_Ts>
|
|
2749
2928
|
inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
|
|
2750
2929
|
{
|
|
2751
|
-
this->wrap_native_method(this->
|
|
2930
|
+
this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
|
|
2752
2931
|
return *this;
|
|
2753
2932
|
}
|
|
2754
2933
|
|
|
@@ -2766,7 +2945,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
|
|
|
2766
2945
|
template<typename Function_T, typename...Arg_Ts>
|
|
2767
2946
|
inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
|
|
2768
2947
|
{
|
|
2769
|
-
this->wrap_native_function(this->
|
|
2948
|
+
this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
|
|
2770
2949
|
return *this;
|
|
2771
2950
|
}
|
|
2772
2951
|
|
|
@@ -2840,7 +3019,7 @@ template<typename Constant_T>
|
|
|
2840
3019
|
inline auto& define_constant(std::string name, Constant_T value)
|
|
2841
3020
|
{
|
|
2842
3021
|
using Base_T = detail::remove_cv_recursive_t<Constant_T>;
|
|
2843
|
-
detail::protect(rb_define_const, this->
|
|
3022
|
+
detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
|
|
2844
3023
|
return *this;
|
|
2845
3024
|
}
|
|
2846
3025
|
};
|
|
@@ -2958,11 +3137,15 @@ namespace Rice4RubyQt6::detail
|
|
|
2958
3137
|
|
|
2959
3138
|
namespace Rice4RubyQt6
|
|
2960
3139
|
{
|
|
2961
|
-
|
|
3140
|
+
struct AttrAccess
|
|
2962
3141
|
{
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
3142
|
+
struct ReadWriteType {};
|
|
3143
|
+
struct ReadType {};
|
|
3144
|
+
struct WriteType {};
|
|
3145
|
+
|
|
3146
|
+
static constexpr ReadWriteType ReadWrite{};
|
|
3147
|
+
static constexpr ReadType Read{};
|
|
3148
|
+
static constexpr WriteType Write{};
|
|
2966
3149
|
};
|
|
2967
3150
|
|
|
2968
3151
|
namespace detail
|
|
@@ -3118,27 +3301,6 @@ namespace Rice4RubyQt6
|
|
|
3118
3301
|
template<typename Constructor_T, typename...Rice_Arg_Ts>
|
|
3119
3302
|
Data_Type<T>& define_constructor(Constructor_T constructor, Rice_Arg_Ts const& ...args);
|
|
3120
3303
|
|
|
3121
|
-
/*! Runs a function that should define this Data_Types methods and attributes.
|
|
3122
|
-
* This is useful when creating classes from a C++ class template.
|
|
3123
|
-
*
|
|
3124
|
-
* \param builder A function that addes methods/attributes to this class
|
|
3125
|
-
*
|
|
3126
|
-
* For example:
|
|
3127
|
-
* \code
|
|
3128
|
-
* void builder(Data_Type<Matrix<T, R, C>>& klass)
|
|
3129
|
-
* {
|
|
3130
|
-
* klass.define_method...
|
|
3131
|
-
* return klass;
|
|
3132
|
-
* }
|
|
3133
|
-
*
|
|
3134
|
-
* define_class<<Matrix<T, R, C>>>("Matrix")
|
|
3135
|
-
* .build(&builder);
|
|
3136
|
-
*
|
|
3137
|
-
* \endcode
|
|
3138
|
-
*/
|
|
3139
|
-
template<typename Func_T>
|
|
3140
|
-
Data_Type<T>& define(Func_T func);
|
|
3141
|
-
|
|
3142
3304
|
//! Register a Director class for this class.
|
|
3143
3305
|
/*! For any class that uses Rice4RubyQt6::Director to enable polymorphism
|
|
3144
3306
|
* across the languages, you need to register that director proxy
|
|
@@ -3189,11 +3351,11 @@ namespace Rice4RubyQt6
|
|
|
3189
3351
|
template<typename Iterator_Func_T>
|
|
3190
3352
|
Data_Type<T>& define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name = "each");
|
|
3191
3353
|
|
|
3192
|
-
template <typename Attribute_T, typename...Arg_Ts>
|
|
3193
|
-
Data_Type<T>& define_attr(std::string name, Attribute_T attribute,
|
|
3194
|
-
|
|
3195
|
-
template <typename Attribute_T, typename...Arg_Ts>
|
|
3196
|
-
Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute,
|
|
3354
|
+
template <typename Attribute_T, typename Access_T = AttrAccess::ReadWriteType, typename...Arg_Ts>
|
|
3355
|
+
Data_Type<T>& define_attr(std::string name, Attribute_T attribute, Access_T access = {}, const Arg_Ts&...args);
|
|
3356
|
+
|
|
3357
|
+
template <typename Attribute_T, typename Access_T = AttrAccess::ReadWriteType, typename...Arg_Ts>
|
|
3358
|
+
Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, Access_T access = {}, const Arg_Ts&...args);
|
|
3197
3359
|
|
|
3198
3360
|
// Include these methods to call methods from Module but return
|
|
3199
3361
|
// an instance of the current classes. This is an alternative to
|
|
@@ -3206,7 +3368,7 @@ namespace Rice4RubyQt6
|
|
|
3206
3368
|
*/
|
|
3207
3369
|
inline auto& include_module(Module const& inc)
|
|
3208
3370
|
{
|
|
3209
|
-
detail::protect(rb_include_module, this->
|
|
3371
|
+
detail::protect(rb_include_module, this->validated_value(), inc.value());
|
|
3210
3372
|
return *this;
|
|
3211
3373
|
}
|
|
3212
3374
|
|
|
@@ -3230,7 +3392,7 @@ inline auto& include_module(Module const& inc)
|
|
|
3230
3392
|
template<typename Method_T, typename...Arg_Ts>
|
|
3231
3393
|
inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
|
|
3232
3394
|
{
|
|
3233
|
-
this->wrap_native_method(this->
|
|
3395
|
+
this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
|
|
3234
3396
|
return *this;
|
|
3235
3397
|
}
|
|
3236
3398
|
|
|
@@ -3248,7 +3410,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
|
|
|
3248
3410
|
template<typename Function_T, typename...Arg_Ts>
|
|
3249
3411
|
inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
|
|
3250
3412
|
{
|
|
3251
|
-
this->wrap_native_function(this->
|
|
3413
|
+
this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
|
|
3252
3414
|
return *this;
|
|
3253
3415
|
}
|
|
3254
3416
|
|
|
@@ -3322,7 +3484,7 @@ template<typename Constant_T>
|
|
|
3322
3484
|
inline auto& define_constant(std::string name, Constant_T value)
|
|
3323
3485
|
{
|
|
3324
3486
|
using Base_T = detail::remove_cv_recursive_t<Constant_T>;
|
|
3325
|
-
detail::protect(rb_define_const, this->
|
|
3487
|
+
detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
|
|
3326
3488
|
return *this;
|
|
3327
3489
|
}
|
|
3328
3490
|
protected:
|
|
@@ -3334,7 +3496,7 @@ inline auto& define_constant(std::string name, Constant_T value)
|
|
|
3334
3496
|
* \return *this
|
|
3335
3497
|
*/
|
|
3336
3498
|
template <typename Base_T = void>
|
|
3337
|
-
static Data_Type<T> bind(const Module& klass);
|
|
3499
|
+
static Data_Type<T> bind(const Module& klass, rb_data_type_t *data_type = nullptr);
|
|
3338
3500
|
|
|
3339
3501
|
template<typename T_, typename Base_T>
|
|
3340
3502
|
friend Rice4RubyQt6::Data_Type<T_> define_class_under(Object parent, Identifier id, Class superKlass);
|
|
@@ -3345,11 +3507,14 @@ inline auto& define_constant(std::string name, Constant_T value)
|
|
|
3345
3507
|
template<typename T_, typename Base_T>
|
|
3346
3508
|
friend Rice4RubyQt6::Data_Type<T_> define_class(char const * name);
|
|
3347
3509
|
|
|
3510
|
+
template<typename T_, typename Base_T>
|
|
3511
|
+
friend Rice4RubyQt6::Data_Type<T_> declare_class_under(Object parent, char const* name, rb_data_type_t *data_type);
|
|
3512
|
+
|
|
3348
3513
|
template<typename Method_T, typename...Arg_Ts>
|
|
3349
3514
|
void wrap_native_method(VALUE klass, std::string name, Method_T&& function, const Arg_Ts&...args);
|
|
3350
3515
|
|
|
3351
|
-
template <typename Attribute_T, typename...Arg_Ts>
|
|
3352
|
-
Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute,
|
|
3516
|
+
template <typename Attribute_T, typename Access_T, typename...Arg_Ts>
|
|
3517
|
+
Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, Access_T access, const Arg_Ts&...args);
|
|
3353
3518
|
|
|
3354
3519
|
private:
|
|
3355
3520
|
template<typename T_>
|
|
@@ -3398,6 +3563,13 @@ inline auto& define_constant(std::string name, Constant_T value)
|
|
|
3398
3563
|
*/
|
|
3399
3564
|
template<typename T, typename Base_T = void>
|
|
3400
3565
|
Data_Type<T> define_class(char const* name);
|
|
3566
|
+
|
|
3567
|
+
//! Identical to define_class_under, except it use an existed RTypedData.
|
|
3568
|
+
/*! This allows you to bind the Data_Type<T> instance in every DLL on Win32
|
|
3569
|
+
* to the same RTypedData, see [issue#355](https://github.com/ruby-rice/rice/issues/355).
|
|
3570
|
+
*/
|
|
3571
|
+
template<typename T, typename Base_T = void>
|
|
3572
|
+
Data_Type<T> declare_class_under(Object parent, char const* name, rb_data_type_t *data_type);
|
|
3401
3573
|
}
|
|
3402
3574
|
|
|
3403
3575
|
|
|
@@ -3635,6 +3807,17 @@ namespace Rice4RubyQt6::detail
|
|
|
3635
3807
|
static inline std::string name = "Float";
|
|
3636
3808
|
};
|
|
3637
3809
|
|
|
3810
|
+
template<>
|
|
3811
|
+
class RubyType<long double>
|
|
3812
|
+
{
|
|
3813
|
+
public:
|
|
3814
|
+
using FromRuby_T = double(*)(VALUE);
|
|
3815
|
+
|
|
3816
|
+
static inline FromRuby_T fromRuby = rb_num2dbl;
|
|
3817
|
+
static inline std::string packTemplate = "d*";
|
|
3818
|
+
static inline std::string name = "Float";
|
|
3819
|
+
};
|
|
3820
|
+
|
|
3638
3821
|
template<>
|
|
3639
3822
|
class RubyType<void>
|
|
3640
3823
|
{
|
|
@@ -3693,7 +3876,10 @@ namespace Rice4RubyQt6::detail
|
|
|
3693
3876
|
VALUE klasses();
|
|
3694
3877
|
|
|
3695
3878
|
private:
|
|
3696
|
-
|
|
3879
|
+
template <typename T>
|
|
3880
|
+
std::type_index key();
|
|
3881
|
+
|
|
3882
|
+
std::optional<std::pair<VALUE, rb_data_type_t*>> lookup(std::type_index typeIndex);
|
|
3697
3883
|
void raiseUnverifiedType(const std::string& typeName);
|
|
3698
3884
|
|
|
3699
3885
|
std::unordered_map<std::type_index, std::pair<VALUE, rb_data_type_t*>> registry_{};
|
|
@@ -3704,32 +3890,40 @@ namespace Rice4RubyQt6::detail
|
|
|
3704
3890
|
|
|
3705
3891
|
// ========= InstanceRegistry.hpp =========
|
|
3706
3892
|
|
|
3893
|
+
#include <type_traits>
|
|
3894
|
+
|
|
3707
3895
|
namespace Rice4RubyQt6::detail
|
|
3708
3896
|
{
|
|
3709
3897
|
class InstanceRegistry
|
|
3710
3898
|
{
|
|
3711
3899
|
public:
|
|
3900
|
+
enum class Mode
|
|
3901
|
+
{
|
|
3902
|
+
Off,
|
|
3903
|
+
Owned,
|
|
3904
|
+
All
|
|
3905
|
+
};
|
|
3906
|
+
|
|
3712
3907
|
template <typename T>
|
|
3713
|
-
VALUE lookup(T
|
|
3908
|
+
VALUE lookup(T* cppInstance, bool isOwner);
|
|
3714
3909
|
|
|
3715
3910
|
template <typename T>
|
|
3716
|
-
|
|
3717
|
-
VALUE lookup(void* cppInstance);
|
|
3911
|
+
void add(T* cppInstance, VALUE rubyInstance, bool isOwner);
|
|
3718
3912
|
|
|
3719
|
-
void add(void* cppInstance, VALUE rubyInstance);
|
|
3720
3913
|
void remove(void* cppInstance);
|
|
3721
3914
|
void clear();
|
|
3722
3915
|
|
|
3723
3916
|
public:
|
|
3724
|
-
|
|
3917
|
+
Mode mode = Mode::Owned;
|
|
3725
3918
|
|
|
3726
3919
|
private:
|
|
3920
|
+
bool shouldTrack(bool isOwner) const;
|
|
3921
|
+
|
|
3727
3922
|
std::map<void*, VALUE> objectMap_;
|
|
3728
3923
|
};
|
|
3729
3924
|
} // namespace Rice4RubyQt6::detail
|
|
3730
3925
|
|
|
3731
3926
|
|
|
3732
|
-
|
|
3733
3927
|
// ========= DefaultHandler.hpp =========
|
|
3734
3928
|
|
|
3735
3929
|
namespace Rice4RubyQt6::detail
|
|
@@ -3844,571 +4038,620 @@ namespace Rice4RubyQt6::detail
|
|
|
3844
4038
|
}
|
|
3845
4039
|
|
|
3846
4040
|
|
|
3847
|
-
// To / From Ruby
|
|
3848
4041
|
|
|
3849
|
-
// =========
|
|
4042
|
+
// ========= Buffer.hpp =========
|
|
4043
|
+
|
|
3850
4044
|
namespace Rice4RubyQt6
|
|
3851
4045
|
{
|
|
3852
|
-
|
|
4046
|
+
template<typename T, typename = void>
|
|
4047
|
+
class Buffer;
|
|
4048
|
+
|
|
4049
|
+
template<typename T>
|
|
4050
|
+
class Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>
|
|
3853
4051
|
{
|
|
3854
|
-
|
|
4052
|
+
public:
|
|
4053
|
+
Buffer(T* pointer);
|
|
4054
|
+
Buffer(T* pointer, size_t size);
|
|
4055
|
+
Buffer(VALUE value);
|
|
4056
|
+
Buffer(VALUE value, size_t size);
|
|
3855
4057
|
|
|
3856
|
-
|
|
3857
|
-
inline Arg& Arg::operator=(Arg_Type val)
|
|
3858
|
-
{
|
|
3859
|
-
this->defaultValue_ = val;
|
|
3860
|
-
return *this;
|
|
3861
|
-
}
|
|
4058
|
+
~Buffer();
|
|
3862
4059
|
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
{
|
|
3866
|
-
return this->defaultValue_.has_value();
|
|
3867
|
-
}
|
|
4060
|
+
Buffer(const Buffer& other) = delete;
|
|
4061
|
+
Buffer(Buffer&& other);
|
|
3868
4062
|
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
template<typename Arg_Type>
|
|
3873
|
-
inline Arg_Type Arg::defaultValue()
|
|
3874
|
-
{
|
|
3875
|
-
return std::any_cast<Arg_Type>(this->defaultValue_);
|
|
3876
|
-
}
|
|
4063
|
+
Buffer& operator=(const Buffer& other) = delete;
|
|
4064
|
+
Buffer& operator=(Buffer&& other);
|
|
4065
|
+
T& operator[](size_t index);
|
|
3877
4066
|
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
return *this;
|
|
3882
|
-
}
|
|
4067
|
+
T* ptr();
|
|
4068
|
+
T& reference();
|
|
4069
|
+
T* release();
|
|
3883
4070
|
|
|
3884
|
-
|
|
3885
|
-
{
|
|
3886
|
-
return this->isKeepAlive_;
|
|
3887
|
-
}
|
|
4071
|
+
size_t size() const;
|
|
3888
4072
|
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
isValue_ = true;
|
|
3892
|
-
return *this;
|
|
3893
|
-
}
|
|
4073
|
+
// Ruby API
|
|
4074
|
+
VALUE toString() const;
|
|
3894
4075
|
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
return isValue_;
|
|
3898
|
-
}
|
|
4076
|
+
VALUE bytes() const;
|
|
4077
|
+
VALUE bytes(size_t count) const;
|
|
3899
4078
|
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
isBlock_ = true;
|
|
3903
|
-
isValue_ = true;
|
|
3904
|
-
return *this;
|
|
3905
|
-
}
|
|
4079
|
+
Array toArray() const;
|
|
4080
|
+
Array toArray(size_t count) const;
|
|
3906
4081
|
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
return isBlock_;
|
|
3910
|
-
}
|
|
4082
|
+
bool isOwner() const;
|
|
4083
|
+
void setOwner(bool value);
|
|
3911
4084
|
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
return *this;
|
|
3916
|
-
}
|
|
4085
|
+
private:
|
|
4086
|
+
void fromBuiltinType(VALUE value, size_t size);
|
|
4087
|
+
void fromWrappedType(VALUE value, size_t size);
|
|
3917
4088
|
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
4089
|
+
bool m_owner = false;
|
|
4090
|
+
size_t m_size = 0;
|
|
4091
|
+
// std::unique_ptr would be great but std::unique_ptr<void> isn't allowed. Mutable is needed to
|
|
4092
|
+
// support const T* buffers
|
|
4093
|
+
mutable T* m_buffer = nullptr;
|
|
4094
|
+
};
|
|
3922
4095
|
|
|
3923
|
-
|
|
4096
|
+
template<typename T>
|
|
4097
|
+
class Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>
|
|
3924
4098
|
{
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
4099
|
+
public:
|
|
4100
|
+
Buffer(T** pointer);
|
|
4101
|
+
Buffer(T** pointer, size_t size);
|
|
4102
|
+
Buffer(VALUE value);
|
|
4103
|
+
Buffer(VALUE value, size_t size);
|
|
3928
4104
|
|
|
3929
|
-
|
|
3930
|
-
{
|
|
3931
|
-
return this->isOwner_;
|
|
3932
|
-
}
|
|
4105
|
+
~Buffer();
|
|
3933
4106
|
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
}
|
|
4107
|
+
Buffer(const Buffer& other) = delete;
|
|
4108
|
+
Buffer(Buffer&& other);
|
|
3937
4109
|
|
|
4110
|
+
Buffer& operator=(const Buffer& other) = delete;
|
|
4111
|
+
Buffer& operator=(Buffer&& other);
|
|
3938
4112
|
|
|
3939
|
-
|
|
3940
|
-
// ========= Parameter.ipp =========
|
|
3941
|
-
namespace Rice4RubyQt6::detail
|
|
3942
|
-
{
|
|
3943
|
-
// ----------- ParameterAbstract ----------------
|
|
3944
|
-
inline ParameterAbstract::ParameterAbstract(std::unique_ptr<Arg>&& arg) : arg_(std::move(arg))
|
|
3945
|
-
{
|
|
3946
|
-
}
|
|
4113
|
+
T* operator[](size_t index);
|
|
3947
4114
|
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
this->arg_ = std::make_unique<Arg>(*other.arg_);
|
|
3951
|
-
}
|
|
4115
|
+
T** ptr();
|
|
4116
|
+
T** release();
|
|
3952
4117
|
|
|
3953
|
-
|
|
3954
|
-
{
|
|
3955
|
-
return this->arg_.get();
|
|
3956
|
-
}
|
|
4118
|
+
size_t size() const;
|
|
3957
4119
|
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
4120
|
+
// Ruby API
|
|
4121
|
+
VALUE toString() const;
|
|
4122
|
+
|
|
4123
|
+
VALUE bytes() const;
|
|
4124
|
+
VALUE bytes(size_t count) const;
|
|
4125
|
+
|
|
4126
|
+
Array toArray() const;
|
|
4127
|
+
Array toArray(size_t count) const;
|
|
4128
|
+
|
|
4129
|
+
void setOwner(bool value);
|
|
4130
|
+
bool isOwner() const;
|
|
4131
|
+
|
|
4132
|
+
private:
|
|
4133
|
+
bool m_owner = false;
|
|
4134
|
+
size_t m_size = 0;
|
|
4135
|
+
T** m_buffer = nullptr;
|
|
4136
|
+
};
|
|
3964
4137
|
|
|
3965
4138
|
template<typename T>
|
|
3966
|
-
|
|
4139
|
+
class Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>
|
|
3967
4140
|
{
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
{
|
|
3974
|
-
return Convertible::Exact;
|
|
3975
|
-
}
|
|
4141
|
+
public:
|
|
4142
|
+
Buffer(T** pointer);
|
|
4143
|
+
Buffer(T** pointer, size_t size);
|
|
4144
|
+
Buffer(VALUE value);
|
|
4145
|
+
Buffer(VALUE value, size_t size);
|
|
3976
4146
|
|
|
3977
|
-
|
|
4147
|
+
~Buffer();
|
|
3978
4148
|
|
|
3979
|
-
|
|
3980
|
-
|
|
4149
|
+
Buffer(const Buffer& other) = delete;
|
|
4150
|
+
Buffer(Buffer&& other);
|
|
3981
4151
|
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
if (result == Convertible::Exact && rb_type(value) == RUBY_T_DATA && !std::is_function_v<std::remove_pointer_t<T>>)
|
|
3985
|
-
{
|
|
3986
|
-
bool isConst = WrapperBase::isConst(value);
|
|
4152
|
+
Buffer& operator=(const Buffer& other) = delete;
|
|
4153
|
+
Buffer& operator=(Buffer&& other);
|
|
3987
4154
|
|
|
3988
|
-
|
|
3989
|
-
if (isConst && !is_const_any_v<T>)
|
|
3990
|
-
{
|
|
3991
|
-
result = Convertible::None;
|
|
3992
|
-
}
|
|
3993
|
-
// It is ok to send a non-const value to a const parameter but
|
|
3994
|
-
// prefer non-const to non-const by slightly decreasing the score
|
|
3995
|
-
else if (!isConst && is_const_any_v<T>)
|
|
3996
|
-
{
|
|
3997
|
-
result = Convertible::ConstMismatch;
|
|
3998
|
-
}
|
|
3999
|
-
}
|
|
4155
|
+
T* operator[](size_t index);
|
|
4000
4156
|
|
|
4001
|
-
|
|
4002
|
-
|
|
4157
|
+
T** ptr();
|
|
4158
|
+
T** release();
|
|
4003
4159
|
|
|
4004
|
-
|
|
4005
|
-
#pragma warning(push)
|
|
4006
|
-
#pragma warning(disable: 4702) // unreachable code
|
|
4007
|
-
#endif
|
|
4160
|
+
size_t size() const;
|
|
4008
4161
|
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
{
|
|
4012
|
-
/* In general the compiler will convert T to const T, but that does not work for converting
|
|
4013
|
-
T** to const T** (see see https://isocpp.org/wiki/faq/const-correctness#constptrptr-conversion)
|
|
4014
|
-
which comes up in the OpenCV bindings.
|
|
4162
|
+
// Ruby API
|
|
4163
|
+
VALUE toString() const;
|
|
4015
4164
|
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
backwards compatible. */
|
|
4165
|
+
VALUE bytes() const;
|
|
4166
|
+
VALUE bytes(size_t count) const;
|
|
4019
4167
|
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
return (T)this->fromRuby_.convert(valueOpt.value());
|
|
4023
|
-
}
|
|
4024
|
-
else if (valueOpt.has_value())
|
|
4025
|
-
{
|
|
4026
|
-
return this->fromRuby_.convert(valueOpt.value());
|
|
4027
|
-
}
|
|
4028
|
-
// Remember std::is_copy_constructible_v<std::vector<std::unique_ptr<T>>>> returns true. Sigh.
|
|
4029
|
-
// So special case vector handling
|
|
4030
|
-
else if constexpr (detail::is_std_vector_v<detail::intrinsic_type<T>>)
|
|
4031
|
-
{
|
|
4032
|
-
if constexpr (std::is_copy_constructible_v<typename detail::intrinsic_type<T>::value_type>)
|
|
4033
|
-
{
|
|
4034
|
-
if (this->arg()->hasDefaultValue())
|
|
4035
|
-
{
|
|
4036
|
-
return this->arg()->template defaultValue<T>();
|
|
4037
|
-
}
|
|
4038
|
-
}
|
|
4039
|
-
}
|
|
4040
|
-
else if constexpr (std::is_copy_constructible_v<T>)
|
|
4041
|
-
{
|
|
4042
|
-
if (this->arg()->hasDefaultValue())
|
|
4043
|
-
{
|
|
4044
|
-
return this->arg()->template defaultValue<T>();
|
|
4045
|
-
}
|
|
4046
|
-
}
|
|
4168
|
+
Array toArray() const;
|
|
4169
|
+
Array toArray(size_t count) const;
|
|
4047
4170
|
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
}
|
|
4171
|
+
void setOwner(bool value);
|
|
4172
|
+
bool isOwner() const;
|
|
4051
4173
|
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4174
|
+
private:
|
|
4175
|
+
bool m_owner = false;
|
|
4176
|
+
size_t m_size = 0;
|
|
4177
|
+
T** m_buffer = nullptr;
|
|
4178
|
+
};
|
|
4055
4179
|
|
|
4056
4180
|
template<typename T>
|
|
4057
|
-
|
|
4181
|
+
class Buffer<T, std::enable_if_t<std::is_void_v<T>>>
|
|
4058
4182
|
{
|
|
4059
|
-
|
|
4060
|
-
|
|
4183
|
+
public:
|
|
4184
|
+
Buffer(T* pointer);
|
|
4185
|
+
Buffer(VALUE value);
|
|
4186
|
+
Buffer(VALUE value, size_t size);
|
|
4187
|
+
|
|
4188
|
+
Buffer(const Buffer& other) = delete;
|
|
4189
|
+
Buffer(Buffer&& other);
|
|
4190
|
+
|
|
4191
|
+
Buffer& operator=(const Buffer& other) = delete;
|
|
4192
|
+
Buffer& operator=(Buffer&& other);
|
|
4061
4193
|
|
|
4194
|
+
size_t size() const;
|
|
4195
|
+
|
|
4196
|
+
VALUE bytes(size_t count) const;
|
|
4197
|
+
VALUE bytes() const;
|
|
4198
|
+
|
|
4199
|
+
T* ptr();
|
|
4200
|
+
T* release();
|
|
4201
|
+
|
|
4202
|
+
private:
|
|
4203
|
+
bool m_owner = false;
|
|
4204
|
+
size_t m_size = 0;
|
|
4205
|
+
T* m_buffer = nullptr;
|
|
4206
|
+
};
|
|
4207
|
+
|
|
4208
|
+
// Specialization for void* - can't create arrays of void, so this is a minimal wrapper
|
|
4062
4209
|
template<typename T>
|
|
4063
|
-
|
|
4210
|
+
class Buffer<T*, std::enable_if_t<std::is_void_v<T>>>
|
|
4064
4211
|
{
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
// So special case vector handling
|
|
4069
|
-
if constexpr (detail::is_std_vector_v<detail::intrinsic_type<T>>)
|
|
4070
|
-
{
|
|
4071
|
-
if constexpr (std::is_copy_constructible_v<typename detail::intrinsic_type<T>::value_type>)
|
|
4072
|
-
{
|
|
4073
|
-
if (this->arg()->hasDefaultValue())
|
|
4074
|
-
{
|
|
4075
|
-
T defaultValue = this->arg()->template defaultValue<T>();
|
|
4076
|
-
return this->toRuby_.convert(defaultValue);
|
|
4077
|
-
}
|
|
4078
|
-
}
|
|
4079
|
-
}
|
|
4080
|
-
else if (this->arg()->hasDefaultValue())
|
|
4081
|
-
{
|
|
4082
|
-
T defaultValue = this->arg()->template defaultValue<T>();
|
|
4083
|
-
return this->toRuby_.convert((remove_cv_recursive_t<T>)defaultValue);
|
|
4084
|
-
}
|
|
4085
|
-
}
|
|
4212
|
+
public:
|
|
4213
|
+
Buffer(T** pointer);
|
|
4214
|
+
Buffer(T** pointer, size_t size);
|
|
4086
4215
|
|
|
4087
|
-
|
|
4088
|
-
|
|
4216
|
+
Buffer(const Buffer& other) = delete;
|
|
4217
|
+
Buffer(Buffer&& other);
|
|
4218
|
+
|
|
4219
|
+
Buffer& operator=(const Buffer& other) = delete;
|
|
4220
|
+
Buffer& operator=(Buffer&& other);
|
|
4221
|
+
|
|
4222
|
+
size_t size() const;
|
|
4223
|
+
|
|
4224
|
+
T** ptr();
|
|
4225
|
+
T** release();
|
|
4226
|
+
|
|
4227
|
+
private:
|
|
4228
|
+
bool m_owner = false;
|
|
4229
|
+
size_t m_size = 0;
|
|
4230
|
+
T** m_buffer = nullptr;
|
|
4231
|
+
};
|
|
4089
4232
|
|
|
4090
4233
|
template<typename T>
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
return typeIndexParser.simplifiedName();
|
|
4095
|
-
}
|
|
4234
|
+
Data_Type<Buffer<T>> define_buffer(std::string klassName = "");
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4096
4237
|
|
|
4238
|
+
// ========= Pointer.hpp =========
|
|
4239
|
+
|
|
4240
|
+
namespace Rice4RubyQt6
|
|
4241
|
+
{
|
|
4097
4242
|
template<typename T>
|
|
4098
|
-
|
|
4243
|
+
class Pointer
|
|
4099
4244
|
{
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4245
|
+
};
|
|
4246
|
+
|
|
4247
|
+
template<typename T>
|
|
4248
|
+
Data_Type<Pointer<T>> define_pointer(std::string klassName = "");
|
|
4103
4249
|
}
|
|
4104
4250
|
|
|
4105
|
-
|
|
4251
|
+
|
|
4252
|
+
// ========= Reference.hpp =========
|
|
4106
4253
|
|
|
4107
4254
|
namespace Rice4RubyQt6
|
|
4108
4255
|
{
|
|
4109
|
-
|
|
4256
|
+
template<typename T>
|
|
4257
|
+
class Reference
|
|
4110
4258
|
{
|
|
4259
|
+
static_assert(!detail::is_wrapped_v<detail::intrinsic_type<T>>,
|
|
4260
|
+
"Reference can only be used with fundamental types");
|
|
4261
|
+
|
|
4111
4262
|
public:
|
|
4112
|
-
|
|
4263
|
+
Reference();
|
|
4264
|
+
Reference(T& data);
|
|
4265
|
+
Reference(VALUE value);
|
|
4266
|
+
T& get();
|
|
4267
|
+
|
|
4268
|
+
private:
|
|
4269
|
+
T data_;
|
|
4113
4270
|
};
|
|
4114
|
-
} // Rice
|
|
4115
4271
|
|
|
4272
|
+
// Specialization needed when VALUE type matches T, causing constructor ambiguity
|
|
4273
|
+
// between Reference(T&) and Reference(VALUE). VALUE is unsigned long when
|
|
4274
|
+
// SIZEOF_LONG == SIZEOF_VOIDP (Linux/macOS) and unsigned long long when
|
|
4275
|
+
// SIZEOF_LONG_LONG == SIZEOF_VOIDP (Windows x64).
|
|
4276
|
+
#if SIZEOF_LONG == SIZEOF_VOIDP
|
|
4277
|
+
template<>
|
|
4278
|
+
class Reference<unsigned long>
|
|
4279
|
+
{
|
|
4280
|
+
public:
|
|
4281
|
+
Reference();
|
|
4282
|
+
Reference(unsigned long value, bool isValue = true);
|
|
4283
|
+
unsigned long& get();
|
|
4116
4284
|
|
|
4117
|
-
|
|
4118
|
-
|
|
4285
|
+
private:
|
|
4286
|
+
unsigned long data_;
|
|
4287
|
+
};
|
|
4288
|
+
#else
|
|
4289
|
+
template<>
|
|
4290
|
+
class Reference<unsigned long long>
|
|
4291
|
+
{
|
|
4292
|
+
public:
|
|
4293
|
+
Reference();
|
|
4294
|
+
Reference(unsigned long long value, bool isValue = true);
|
|
4295
|
+
unsigned long long& get();
|
|
4119
4296
|
|
|
4297
|
+
private:
|
|
4298
|
+
unsigned long long data_;
|
|
4299
|
+
};
|
|
4300
|
+
#endif
|
|
4301
|
+
|
|
4302
|
+
template<typename T>
|
|
4303
|
+
Data_Type<Reference<T>> define_reference(std::string klassName = "");
|
|
4304
|
+
}
|
|
4305
|
+
|
|
4306
|
+
|
|
4307
|
+
// To / From Ruby
|
|
4308
|
+
|
|
4309
|
+
// ========= Arg.ipp =========
|
|
4120
4310
|
namespace Rice4RubyQt6
|
|
4121
4311
|
{
|
|
4122
|
-
inline
|
|
4312
|
+
inline Arg::Arg(std::string name) : name(name)
|
|
4123
4313
|
{
|
|
4124
4314
|
}
|
|
4125
4315
|
|
|
4126
|
-
|
|
4316
|
+
template<typename Arg_Type>
|
|
4317
|
+
inline Arg& Arg::operator=(Arg_Type val)
|
|
4127
4318
|
{
|
|
4128
|
-
|
|
4319
|
+
this->defaultValue_ = val;
|
|
4129
4320
|
return *this;
|
|
4130
4321
|
}
|
|
4131
4322
|
|
|
4132
|
-
|
|
4323
|
+
//! Check if this Arg has a default value associated with it
|
|
4324
|
+
inline bool Arg::hasDefaultValue() const
|
|
4133
4325
|
{
|
|
4134
|
-
|
|
4135
|
-
return *this;
|
|
4326
|
+
return this->defaultValue_.has_value();
|
|
4136
4327
|
}
|
|
4137
4328
|
|
|
4138
|
-
|
|
4329
|
+
//! Return a reference to the default value associated with this Arg
|
|
4330
|
+
/*! \return the type saved to this Arg
|
|
4331
|
+
*/
|
|
4332
|
+
template<typename Arg_Type>
|
|
4333
|
+
inline Arg_Type Arg::defaultValue()
|
|
4139
4334
|
{
|
|
4140
|
-
|
|
4141
|
-
return *this;
|
|
4335
|
+
return std::any_cast<Arg_Type>(this->defaultValue_);
|
|
4142
4336
|
}
|
|
4143
4337
|
|
|
4144
|
-
inline
|
|
4338
|
+
inline Arg& Arg::keepAlive()
|
|
4145
4339
|
{
|
|
4146
|
-
|
|
4340
|
+
this->isKeepAlive_ = true;
|
|
4147
4341
|
return *this;
|
|
4148
4342
|
}
|
|
4149
|
-
} // Rice
|
|
4150
4343
|
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
namespace Rice4RubyQt6
|
|
4154
|
-
{
|
|
4155
|
-
//! Define a Type's Constructor and it's arguments.
|
|
4156
|
-
/*! E.g. for the default constructor on a Type:
|
|
4157
|
-
\code
|
|
4158
|
-
define_class<Test>()
|
|
4159
|
-
.define_constructor(Constructor<Test>());
|
|
4160
|
-
\endcode
|
|
4161
|
-
*
|
|
4162
|
-
* The first template argument must be the type being wrapped.
|
|
4163
|
-
* Additional arguments must be the types of the parameters sent
|
|
4164
|
-
* to the constructor.
|
|
4165
|
-
*
|
|
4166
|
-
* For more information, see Rice4RubyQt6::Data_Type::define_constructor.
|
|
4167
|
-
*/
|
|
4168
|
-
template<typename T, typename...Parameter_Ts>
|
|
4169
|
-
class Constructor;
|
|
4170
|
-
}
|
|
4171
|
-
|
|
4172
|
-
// ========= Buffer.hpp =========
|
|
4173
|
-
|
|
4174
|
-
namespace Rice4RubyQt6
|
|
4175
|
-
{
|
|
4176
|
-
template<typename T, typename = void>
|
|
4177
|
-
class Buffer;
|
|
4178
|
-
|
|
4179
|
-
template<typename T>
|
|
4180
|
-
class Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>
|
|
4344
|
+
inline bool Arg::isKeepAlive() const
|
|
4181
4345
|
{
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
Buffer(T* pointer, size_t size);
|
|
4185
|
-
Buffer(VALUE value);
|
|
4186
|
-
Buffer(VALUE value, size_t size);
|
|
4346
|
+
return this->isKeepAlive_;
|
|
4347
|
+
}
|
|
4187
4348
|
|
|
4188
|
-
|
|
4349
|
+
inline Arg& Arg::setValue()
|
|
4350
|
+
{
|
|
4351
|
+
isValue_ = true;
|
|
4352
|
+
return *this;
|
|
4353
|
+
}
|
|
4189
4354
|
|
|
4190
|
-
|
|
4191
|
-
|
|
4355
|
+
inline bool Arg::isValue() const
|
|
4356
|
+
{
|
|
4357
|
+
return isValue_;
|
|
4358
|
+
}
|
|
4192
4359
|
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4360
|
+
inline Arg& Arg::setOpaque()
|
|
4361
|
+
{
|
|
4362
|
+
isOpaque_ = true;
|
|
4363
|
+
return *this;
|
|
4364
|
+
}
|
|
4196
4365
|
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4366
|
+
inline bool Arg::isOpaque() const
|
|
4367
|
+
{
|
|
4368
|
+
return isOpaque_;
|
|
4369
|
+
}
|
|
4200
4370
|
|
|
4201
|
-
|
|
4371
|
+
inline Arg& Arg::takeOwnership()
|
|
4372
|
+
{
|
|
4373
|
+
this->isOwner_ = true;
|
|
4374
|
+
return *this;
|
|
4375
|
+
}
|
|
4202
4376
|
|
|
4203
|
-
|
|
4204
|
-
|
|
4377
|
+
inline bool Arg::isOwner()
|
|
4378
|
+
{
|
|
4379
|
+
return this->isOwner_;
|
|
4380
|
+
}
|
|
4205
4381
|
|
|
4206
|
-
|
|
4207
|
-
|
|
4382
|
+
inline ArgBuffer::ArgBuffer(std::string name) : Arg(name)
|
|
4383
|
+
{
|
|
4384
|
+
}
|
|
4208
4385
|
|
|
4209
|
-
Array toArray() const;
|
|
4210
|
-
Array toArray(size_t count) const;
|
|
4211
4386
|
|
|
4212
|
-
|
|
4213
|
-
|
|
4387
|
+
} // Rice
|
|
4388
|
+
// ========= Parameter.ipp =========
|
|
4389
|
+
namespace Rice4RubyQt6::detail
|
|
4390
|
+
{
|
|
4391
|
+
// ----------- ParameterAbstract ----------------
|
|
4392
|
+
inline ParameterAbstract::ParameterAbstract(std::unique_ptr<Arg>&& arg) : arg_(std::move(arg))
|
|
4393
|
+
{
|
|
4394
|
+
}
|
|
4214
4395
|
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4396
|
+
inline ParameterAbstract::ParameterAbstract(const ParameterAbstract& other)
|
|
4397
|
+
{
|
|
4398
|
+
this->arg_ = std::make_unique<Arg>(*other.arg_);
|
|
4399
|
+
}
|
|
4218
4400
|
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
mutable T* m_buffer = nullptr;
|
|
4224
|
-
};
|
|
4401
|
+
inline Arg* ParameterAbstract::arg()
|
|
4402
|
+
{
|
|
4403
|
+
return this->arg_.get();
|
|
4404
|
+
}
|
|
4225
4405
|
|
|
4406
|
+
// ----------- Parameter ----------------
|
|
4226
4407
|
template<typename T>
|
|
4227
|
-
|
|
4408
|
+
inline Parameter<T>::Parameter(std::unique_ptr<Arg>&& arg) : ParameterAbstract(std::move(arg)),
|
|
4409
|
+
fromRuby_(this->arg()), toRuby_(this->arg())
|
|
4228
4410
|
{
|
|
4229
|
-
|
|
4230
|
-
Buffer(T** pointer);
|
|
4231
|
-
Buffer(T** pointer, size_t size);
|
|
4232
|
-
Buffer(VALUE value);
|
|
4233
|
-
Buffer(VALUE value, size_t size);
|
|
4234
|
-
|
|
4235
|
-
~Buffer();
|
|
4236
|
-
|
|
4237
|
-
Buffer(const Buffer& other) = delete;
|
|
4238
|
-
Buffer(Buffer&& other);
|
|
4239
|
-
|
|
4240
|
-
Buffer& operator=(const Buffer& other) = delete;
|
|
4241
|
-
Buffer& operator=(Buffer&& other);
|
|
4242
|
-
|
|
4243
|
-
T* operator[](size_t index);
|
|
4244
|
-
|
|
4245
|
-
T** ptr();
|
|
4246
|
-
T** release();
|
|
4247
|
-
|
|
4248
|
-
size_t size() const;
|
|
4249
|
-
|
|
4250
|
-
// Ruby API
|
|
4251
|
-
VALUE toString() const;
|
|
4252
|
-
|
|
4253
|
-
VALUE bytes() const;
|
|
4254
|
-
VALUE bytes(size_t count) const;
|
|
4255
|
-
|
|
4256
|
-
Array toArray() const;
|
|
4257
|
-
Array toArray(size_t count) const;
|
|
4258
|
-
|
|
4259
|
-
void setOwner(bool value);
|
|
4260
|
-
bool isOwner() const;
|
|
4261
|
-
|
|
4262
|
-
private:
|
|
4263
|
-
bool m_owner = false;
|
|
4264
|
-
size_t m_size = 0;
|
|
4265
|
-
T** m_buffer = nullptr;
|
|
4266
|
-
};
|
|
4411
|
+
}
|
|
4267
4412
|
|
|
4268
4413
|
template<typename T>
|
|
4269
|
-
|
|
4414
|
+
inline double Parameter<T>::matches(std::optional<VALUE>& valueOpt)
|
|
4270
4415
|
{
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4416
|
+
if (!valueOpt.has_value())
|
|
4417
|
+
{
|
|
4418
|
+
return Convertible::None;
|
|
4419
|
+
}
|
|
4420
|
+
else if (this->arg()->isValue())
|
|
4421
|
+
{
|
|
4422
|
+
return Convertible::Exact;
|
|
4423
|
+
}
|
|
4276
4424
|
|
|
4277
|
-
|
|
4425
|
+
VALUE value = valueOpt.value();
|
|
4278
4426
|
|
|
4279
|
-
|
|
4280
|
-
|
|
4427
|
+
// Check with FromRuby if the VALUE is convertible to C++
|
|
4428
|
+
double result = this->fromRuby_.is_convertible(value);
|
|
4281
4429
|
|
|
4282
|
-
|
|
4283
|
-
|
|
4430
|
+
// TODO this is ugly and hacky and probably doesn't belong here.
|
|
4431
|
+
// Some Ruby objects like Proc and Set (in Ruby 4+) are also RUBY_T_DATA so we have to check for them
|
|
4432
|
+
if (result == Convertible::Exact && rb_type(value) == RUBY_T_DATA)
|
|
4433
|
+
{
|
|
4434
|
+
bool isBuffer = dynamic_cast<ArgBuffer*>(this->arg()) ? true : false;
|
|
4435
|
+
if ((!isBuffer && Data_Type<detail::intrinsic_type<T>>::is_descendant(value)) ||
|
|
4436
|
+
(isBuffer && Data_Type<Pointer<detail::intrinsic_type<T>>>::is_descendant(value)))
|
|
4437
|
+
{
|
|
4438
|
+
bool isConst = WrapperBase::isConst(value);
|
|
4284
4439
|
|
|
4285
|
-
|
|
4440
|
+
// Do not send a const value to a non-const parameter
|
|
4441
|
+
if (isConst && !is_const_any_v<T>)
|
|
4442
|
+
{
|
|
4443
|
+
result = Convertible::None;
|
|
4444
|
+
}
|
|
4445
|
+
// It is ok to send a non-const value to a const parameter but
|
|
4446
|
+
// prefer non-const to non-const by slightly decreasing the score
|
|
4447
|
+
else if (!isConst && is_const_any_v<T>)
|
|
4448
|
+
{
|
|
4449
|
+
result = Convertible::ConstMismatch;
|
|
4450
|
+
}
|
|
4451
|
+
}
|
|
4452
|
+
}
|
|
4286
4453
|
|
|
4287
|
-
|
|
4288
|
-
|
|
4454
|
+
return result;
|
|
4455
|
+
}
|
|
4289
4456
|
|
|
4290
|
-
|
|
4457
|
+
#ifdef _MSC_VER
|
|
4458
|
+
#pragma warning(push)
|
|
4459
|
+
#pragma warning(disable: 4702) // unreachable code
|
|
4460
|
+
#endif
|
|
4291
4461
|
|
|
4292
|
-
|
|
4293
|
-
|
|
4462
|
+
template<typename T>
|
|
4463
|
+
inline T Parameter<T>::convertToNative(std::optional<VALUE>& valueOpt)
|
|
4464
|
+
{
|
|
4465
|
+
/* In general the compiler will convert T to const T, but that does not work for converting
|
|
4466
|
+
T** to const T** (see see https://isocpp.org/wiki/faq/const-correctness#constptrptr-conversion)
|
|
4467
|
+
which comes up in the OpenCV bindings.
|
|
4294
4468
|
|
|
4295
|
-
|
|
4296
|
-
|
|
4469
|
+
An alternative solution is updating From_Ruby#convert to become a templated function that specifies
|
|
4470
|
+
the return type. That works but requires a lot more code changes for this one case and is not
|
|
4471
|
+
backwards compatible. */
|
|
4297
4472
|
|
|
4298
|
-
|
|
4299
|
-
|
|
4473
|
+
if constexpr (is_pointer_pointer_v<T> && !std::is_convertible_v<remove_cv_recursive_t<T>, T>)
|
|
4474
|
+
{
|
|
4475
|
+
return (T)this->fromRuby_.convert(valueOpt.value());
|
|
4476
|
+
}
|
|
4477
|
+
else if (valueOpt.has_value())
|
|
4478
|
+
{
|
|
4479
|
+
return this->fromRuby_.convert(valueOpt.value());
|
|
4480
|
+
}
|
|
4481
|
+
// Remember std::is_copy_constructible_v<std::vector<std::unique_ptr<T>>>> returns true. Sigh.
|
|
4482
|
+
// So special case vector handling
|
|
4483
|
+
else if constexpr (detail::is_std_vector_v<detail::intrinsic_type<T>>)
|
|
4484
|
+
{
|
|
4485
|
+
if constexpr (std::is_copy_constructible_v<typename detail::intrinsic_type<T>::value_type>)
|
|
4486
|
+
{
|
|
4487
|
+
if (this->arg()->hasDefaultValue())
|
|
4488
|
+
{
|
|
4489
|
+
return this->arg()->template defaultValue<T>();
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
// Incomplete types can't have default values (std::any requires complete types)
|
|
4494
|
+
else if constexpr (!is_complete_v<intrinsic_type<T>>)
|
|
4495
|
+
{
|
|
4496
|
+
// No default value possible for incomplete types
|
|
4497
|
+
}
|
|
4498
|
+
else if constexpr (std::is_copy_constructible_v<T>)
|
|
4499
|
+
{
|
|
4500
|
+
if (this->arg()->hasDefaultValue())
|
|
4501
|
+
{
|
|
4502
|
+
return this->arg()->template defaultValue<T>();
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4300
4505
|
|
|
4301
|
-
|
|
4302
|
-
|
|
4506
|
+
// This can be unreachable code
|
|
4507
|
+
throw std::invalid_argument("Could not convert Ruby value");
|
|
4508
|
+
}
|
|
4303
4509
|
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
T** m_buffer = nullptr;
|
|
4308
|
-
};
|
|
4510
|
+
#ifdef _MSC_VER
|
|
4511
|
+
#pragma warning(pop)
|
|
4512
|
+
#endif
|
|
4309
4513
|
|
|
4310
4514
|
template<typename T>
|
|
4311
|
-
|
|
4515
|
+
inline VALUE Parameter<T>::convertToRuby(T& object)
|
|
4312
4516
|
{
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
Buffer(VALUE value);
|
|
4316
|
-
Buffer(VALUE value, size_t size);
|
|
4317
|
-
|
|
4318
|
-
Buffer(const Buffer& other) = delete;
|
|
4319
|
-
Buffer(Buffer&& other);
|
|
4517
|
+
return this->toRuby_.convert(object);
|
|
4518
|
+
}
|
|
4320
4519
|
|
|
4321
|
-
|
|
4322
|
-
|
|
4520
|
+
template<typename T>
|
|
4521
|
+
inline VALUE Parameter<T>::defaultValueRuby()
|
|
4522
|
+
{
|
|
4523
|
+
using To_Ruby_T = remove_cv_recursive_t<T>;
|
|
4323
4524
|
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4525
|
+
if (!this->arg()->hasDefaultValue())
|
|
4526
|
+
{
|
|
4527
|
+
throw std::runtime_error("No default value set for " + this->arg()->name);
|
|
4528
|
+
}
|
|
4328
4529
|
|
|
4329
|
-
|
|
4330
|
-
|
|
4530
|
+
if constexpr (!is_complete_v<intrinsic_type<T>>)
|
|
4531
|
+
{
|
|
4532
|
+
// Only pointers to incomplete types can have
|
|
4533
|
+
// default values (e.g., void* or Impl*), since the pointer itself is complete.
|
|
4534
|
+
// References and values of incomplete types cannot be stored in std::any.
|
|
4535
|
+
if constexpr (std::is_pointer_v<std::remove_reference_t<T>>)
|
|
4536
|
+
{
|
|
4537
|
+
T defaultValue = this->arg()->template defaultValue<T>();
|
|
4538
|
+
return this->toRuby_.convert((To_Ruby_T)defaultValue);
|
|
4539
|
+
}
|
|
4540
|
+
else
|
|
4541
|
+
{
|
|
4542
|
+
throw std::runtime_error("Default value not allowed for incomple type. Parameter " + this->arg()->name);
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
else if constexpr (std::is_constructible_v<std::remove_cv_t<T>, std::remove_cv_t<std::remove_reference_t<T>>&>)
|
|
4546
|
+
{
|
|
4547
|
+
// Remember std::is_copy_constructible_v<std::vector<std::unique_ptr<T>>>> returns true. Sigh.
|
|
4548
|
+
// So special case vector handling
|
|
4549
|
+
if constexpr (detail::is_std_vector_v<detail::intrinsic_type<T>>)
|
|
4550
|
+
{
|
|
4551
|
+
if constexpr (std::is_copy_constructible_v<typename detail::intrinsic_type<T>::value_type>)
|
|
4552
|
+
{
|
|
4553
|
+
T defaultValue = this->arg()->template defaultValue<T>();
|
|
4554
|
+
return this->toRuby_.convert(defaultValue);
|
|
4555
|
+
}
|
|
4556
|
+
else
|
|
4557
|
+
{
|
|
4558
|
+
throw std::runtime_error("Default value not allowed for parameter " + this->arg()->name);
|
|
4559
|
+
}
|
|
4560
|
+
}
|
|
4561
|
+
else
|
|
4562
|
+
{
|
|
4563
|
+
T defaultValue = this->arg()->template defaultValue<T>();
|
|
4564
|
+
return this->toRuby_.convert((To_Ruby_T)defaultValue);
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
else
|
|
4568
|
+
{
|
|
4569
|
+
throw std::runtime_error("Default value not allowed for parameter " + this->arg()->name);
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4331
4572
|
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
T
|
|
4336
|
-
|
|
4573
|
+
template<typename T>
|
|
4574
|
+
inline std::string Parameter<T>::cppTypeName()
|
|
4575
|
+
{
|
|
4576
|
+
detail::TypeDetail<T> typeDetail;
|
|
4577
|
+
return typeDetail.simplifiedName();
|
|
4578
|
+
}
|
|
4337
4579
|
|
|
4338
4580
|
template<typename T>
|
|
4339
|
-
|
|
4581
|
+
inline VALUE Parameter<T>::klass()
|
|
4582
|
+
{
|
|
4583
|
+
TypeDetail<T> typeDetail;
|
|
4584
|
+
return typeDetail.rubyKlass();
|
|
4585
|
+
}
|
|
4340
4586
|
}
|
|
4341
4587
|
|
|
4342
|
-
|
|
4343
|
-
// ========= Pointer.hpp =========
|
|
4588
|
+
// ========= NoGVL.hpp =========
|
|
4344
4589
|
|
|
4345
4590
|
namespace Rice4RubyQt6
|
|
4346
4591
|
{
|
|
4347
|
-
|
|
4348
|
-
class Pointer
|
|
4592
|
+
class NoGVL
|
|
4349
4593
|
{
|
|
4594
|
+
public:
|
|
4595
|
+
NoGVL() = default;
|
|
4350
4596
|
};
|
|
4351
|
-
|
|
4352
|
-
template<typename T>
|
|
4353
|
-
Data_Type<Pointer<T>> define_pointer(std::string klassName = "");
|
|
4354
|
-
}
|
|
4597
|
+
} // Rice
|
|
4355
4598
|
|
|
4356
4599
|
|
|
4357
|
-
// =========
|
|
4600
|
+
// ========= Return.ipp =========
|
|
4601
|
+
#include <any>
|
|
4358
4602
|
|
|
4359
4603
|
namespace Rice4RubyQt6
|
|
4360
4604
|
{
|
|
4361
|
-
|
|
4362
|
-
class Reference
|
|
4605
|
+
inline Return::Return(): Arg("Return")
|
|
4363
4606
|
{
|
|
4364
|
-
|
|
4365
|
-
"Reference can only be used with fundamental types");
|
|
4607
|
+
}
|
|
4366
4608
|
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4609
|
+
inline Return& Return::keepAlive()
|
|
4610
|
+
{
|
|
4611
|
+
Arg::keepAlive();
|
|
4612
|
+
return *this;
|
|
4613
|
+
}
|
|
4372
4614
|
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4615
|
+
inline Return& Return::setValue()
|
|
4616
|
+
{
|
|
4617
|
+
Arg::setValue();
|
|
4618
|
+
return *this;
|
|
4619
|
+
}
|
|
4376
4620
|
|
|
4377
|
-
|
|
4378
|
-
// between Reference(T&) and Reference(VALUE). VALUE is unsigned long when
|
|
4379
|
-
// SIZEOF_LONG == SIZEOF_VOIDP (Linux/macOS) and unsigned long long when
|
|
4380
|
-
// SIZEOF_LONG_LONG == SIZEOF_VOIDP (Windows x64).
|
|
4381
|
-
#if SIZEOF_LONG == SIZEOF_VOIDP
|
|
4382
|
-
template<>
|
|
4383
|
-
class Reference<unsigned long>
|
|
4621
|
+
inline Return& Return::setOpaque()
|
|
4384
4622
|
{
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
unsigned long& get();
|
|
4623
|
+
Arg::setOpaque();
|
|
4624
|
+
return *this;
|
|
4625
|
+
}
|
|
4389
4626
|
|
|
4390
|
-
|
|
4391
|
-
unsigned long data_;
|
|
4392
|
-
};
|
|
4393
|
-
#else
|
|
4394
|
-
template<>
|
|
4395
|
-
class Reference<unsigned long long>
|
|
4627
|
+
inline Return& Return::takeOwnership()
|
|
4396
4628
|
{
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4629
|
+
Arg::takeOwnership();
|
|
4630
|
+
return *this;
|
|
4631
|
+
}
|
|
4632
|
+
} // Rice
|
|
4401
4633
|
|
|
4402
|
-
|
|
4403
|
-
unsigned long long data_;
|
|
4404
|
-
};
|
|
4405
|
-
#endif
|
|
4634
|
+
// ========= Constructor.hpp =========
|
|
4406
4635
|
|
|
4407
|
-
|
|
4408
|
-
|
|
4636
|
+
namespace Rice4RubyQt6
|
|
4637
|
+
{
|
|
4638
|
+
//! Define a Type's Constructor and it's arguments.
|
|
4639
|
+
/*! E.g. for the default constructor on a Type:
|
|
4640
|
+
\code
|
|
4641
|
+
define_class<Test>()
|
|
4642
|
+
.define_constructor(Constructor<Test>());
|
|
4643
|
+
\endcode
|
|
4644
|
+
*
|
|
4645
|
+
* The first template argument must be the type being wrapped.
|
|
4646
|
+
* Additional arguments must be the types of the parameters sent
|
|
4647
|
+
* to the constructor.
|
|
4648
|
+
*
|
|
4649
|
+
* For more information, see Rice4RubyQt6::Data_Type::define_constructor.
|
|
4650
|
+
*/
|
|
4651
|
+
template<typename T, typename...Parameter_Ts>
|
|
4652
|
+
class Constructor;
|
|
4409
4653
|
}
|
|
4410
4654
|
|
|
4411
|
-
|
|
4412
4655
|
// ========= Buffer.ipp =========
|
|
4413
4656
|
namespace Rice4RubyQt6
|
|
4414
4657
|
{
|
|
@@ -4527,8 +4770,8 @@ namespace Rice4RubyQt6
|
|
|
4527
4770
|
}
|
|
4528
4771
|
else
|
|
4529
4772
|
{
|
|
4530
|
-
detail::
|
|
4531
|
-
std::string typeName =
|
|
4773
|
+
detail::TypeDetail<T> typeDetail;
|
|
4774
|
+
std::string typeName = typeDetail.name();
|
|
4532
4775
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
|
|
4533
4776
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
4534
4777
|
}
|
|
@@ -4567,9 +4810,9 @@ namespace Rice4RubyQt6
|
|
|
4567
4810
|
}
|
|
4568
4811
|
else
|
|
4569
4812
|
{
|
|
4570
|
-
detail::
|
|
4813
|
+
detail::TypeDetail<Intrinsic_T> typeDetail;
|
|
4571
4814
|
throw Exception(rb_eTypeError, "Cannot construct object of type %s - type is not move or copy constructible",
|
|
4572
|
-
|
|
4815
|
+
typeDetail.name().c_str());
|
|
4573
4816
|
}
|
|
4574
4817
|
}
|
|
4575
4818
|
break;
|
|
@@ -4609,8 +4852,8 @@ namespace Rice4RubyQt6
|
|
|
4609
4852
|
}
|
|
4610
4853
|
default:
|
|
4611
4854
|
{
|
|
4612
|
-
detail::
|
|
4613
|
-
std::string typeName =
|
|
4855
|
+
detail::TypeDetail<T> typeDetail;
|
|
4856
|
+
std::string typeName = typeDetail.name();
|
|
4614
4857
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
|
|
4615
4858
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
4616
4859
|
}
|
|
@@ -4680,8 +4923,8 @@ namespace Rice4RubyQt6
|
|
|
4680
4923
|
template<typename T>
|
|
4681
4924
|
inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::toString() const
|
|
4682
4925
|
{
|
|
4683
|
-
detail::
|
|
4684
|
-
std::string description = "Buffer<type: " +
|
|
4926
|
+
detail::TypeDetail<T*> typeDetail;
|
|
4927
|
+
std::string description = "Buffer<type: " + typeDetail.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
|
|
4685
4928
|
|
|
4686
4929
|
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
|
4687
4930
|
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
|
@@ -4753,22 +4996,22 @@ namespace Rice4RubyQt6
|
|
|
4753
4996
|
|
|
4754
4997
|
// ---- Buffer<T*> - Builtin -------
|
|
4755
4998
|
template<typename T>
|
|
4756
|
-
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer) : m_buffer(pointer)
|
|
4999
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::Buffer(T** pointer) : m_buffer(pointer)
|
|
4757
5000
|
{
|
|
4758
5001
|
}
|
|
4759
5002
|
|
|
4760
5003
|
template<typename T>
|
|
4761
|
-
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_size(size), m_buffer(pointer)
|
|
5004
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::Buffer(T** pointer, size_t size) : m_size(size), m_buffer(pointer)
|
|
4762
5005
|
{
|
|
4763
5006
|
}
|
|
4764
5007
|
|
|
4765
5008
|
template <typename T>
|
|
4766
|
-
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(VALUE value) : Buffer(value, 0)
|
|
5009
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::Buffer(VALUE value) : Buffer(value, 0)
|
|
4767
5010
|
{
|
|
4768
5011
|
}
|
|
4769
5012
|
|
|
4770
5013
|
template <typename T>
|
|
4771
|
-
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(VALUE value, size_t size)
|
|
5014
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::Buffer(VALUE value, size_t size)
|
|
4772
5015
|
{
|
|
4773
5016
|
using Intrinsic_T = typename detail::intrinsic_type<T>;
|
|
4774
5017
|
|
|
@@ -4803,7 +5046,7 @@ namespace Rice4RubyQt6
|
|
|
4803
5046
|
if (inner.size() != 1)
|
|
4804
5047
|
{
|
|
4805
5048
|
throw Exception(rb_eTypeError, "Expected inner array size 1 for type %s* but got %ld",
|
|
4806
|
-
detail::
|
|
5049
|
+
detail::TypeDetail<T>().name().c_str(), inner.size());
|
|
4807
5050
|
}
|
|
4808
5051
|
this->m_buffer[i] = fromRuby.convert(inner[0].value());
|
|
4809
5052
|
}
|
|
@@ -4825,8 +5068,8 @@ namespace Rice4RubyQt6
|
|
|
4825
5068
|
}
|
|
4826
5069
|
default:
|
|
4827
5070
|
{
|
|
4828
|
-
detail::
|
|
4829
|
-
std::string typeName =
|
|
5071
|
+
detail::TypeDetail<T> typeDetail;
|
|
5072
|
+
std::string typeName = typeDetail.name();
|
|
4830
5073
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
|
|
4831
5074
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
4832
5075
|
}
|
|
@@ -4834,7 +5077,7 @@ namespace Rice4RubyQt6
|
|
|
4834
5077
|
}
|
|
4835
5078
|
|
|
4836
5079
|
template <typename T>
|
|
4837
|
-
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::~Buffer()
|
|
5080
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::~Buffer()
|
|
4838
5081
|
{
|
|
4839
5082
|
if (this->m_owner)
|
|
4840
5083
|
{
|
|
@@ -4848,7 +5091,7 @@ namespace Rice4RubyQt6
|
|
|
4848
5091
|
}
|
|
4849
5092
|
|
|
4850
5093
|
template <typename T>
|
|
4851
|
-
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size),
|
|
5094
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::Buffer(Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size),
|
|
4852
5095
|
m_buffer(other.m_buffer)
|
|
4853
5096
|
{
|
|
4854
5097
|
other.m_buffer = nullptr;
|
|
@@ -4857,7 +5100,7 @@ namespace Rice4RubyQt6
|
|
|
4857
5100
|
}
|
|
4858
5101
|
|
|
4859
5102
|
template <typename T>
|
|
4860
|
-
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>& Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::operator=(Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>&& other)
|
|
5103
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>& Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::operator=(Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>&& other)
|
|
4861
5104
|
{
|
|
4862
5105
|
this->m_buffer = other.m_buffer;
|
|
4863
5106
|
other.m_buffer = nullptr;
|
|
@@ -4872,54 +5115,54 @@ namespace Rice4RubyQt6
|
|
|
4872
5115
|
}
|
|
4873
5116
|
|
|
4874
5117
|
template <typename T>
|
|
4875
|
-
inline T* Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::operator[](size_t index)
|
|
5118
|
+
inline T* Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::operator[](size_t index)
|
|
4876
5119
|
{
|
|
4877
5120
|
return this->m_buffer[index];
|
|
4878
5121
|
}
|
|
4879
5122
|
|
|
4880
5123
|
template <typename T>
|
|
4881
|
-
inline size_t Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::size() const
|
|
5124
|
+
inline size_t Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::size() const
|
|
4882
5125
|
{
|
|
4883
5126
|
return this->m_size;
|
|
4884
5127
|
}
|
|
4885
5128
|
|
|
4886
5129
|
template <typename T>
|
|
4887
|
-
inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::ptr()
|
|
5130
|
+
inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::ptr()
|
|
4888
5131
|
{
|
|
4889
5132
|
return this->m_buffer;
|
|
4890
5133
|
}
|
|
4891
5134
|
|
|
4892
5135
|
template <typename T>
|
|
4893
|
-
inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::release()
|
|
5136
|
+
inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::release()
|
|
4894
5137
|
{
|
|
4895
5138
|
this->m_owner = false;
|
|
4896
5139
|
return this->m_buffer;
|
|
4897
5140
|
}
|
|
4898
5141
|
|
|
4899
5142
|
template <typename T>
|
|
4900
|
-
inline bool Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::isOwner() const
|
|
5143
|
+
inline bool Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::isOwner() const
|
|
4901
5144
|
{
|
|
4902
5145
|
return this->m_owner;
|
|
4903
5146
|
}
|
|
4904
5147
|
|
|
4905
5148
|
template <typename T>
|
|
4906
|
-
inline void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::setOwner(bool value)
|
|
5149
|
+
inline void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::setOwner(bool value)
|
|
4907
5150
|
{
|
|
4908
5151
|
this->m_owner = value;
|
|
4909
5152
|
}
|
|
4910
5153
|
|
|
4911
5154
|
template<typename T>
|
|
4912
|
-
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toString() const
|
|
5155
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::toString() const
|
|
4913
5156
|
{
|
|
4914
|
-
detail::
|
|
4915
|
-
std::string description = "Buffer<type: " +
|
|
5157
|
+
detail::TypeDetail<T*> typeDetail;
|
|
5158
|
+
std::string description = "Buffer<type: " + typeDetail.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
|
|
4916
5159
|
|
|
4917
5160
|
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
|
4918
5161
|
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
|
4919
5162
|
}
|
|
4920
5163
|
|
|
4921
5164
|
template<typename T>
|
|
4922
|
-
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes(size_t count) const
|
|
5165
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::bytes(size_t count) const
|
|
4923
5166
|
{
|
|
4924
5167
|
if (!this->m_buffer)
|
|
4925
5168
|
{
|
|
@@ -4934,13 +5177,13 @@ namespace Rice4RubyQt6
|
|
|
4934
5177
|
}
|
|
4935
5178
|
|
|
4936
5179
|
template<typename T>
|
|
4937
|
-
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes() const
|
|
5180
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::bytes() const
|
|
4938
5181
|
{
|
|
4939
5182
|
return this->bytes(this->m_size);
|
|
4940
5183
|
}
|
|
4941
5184
|
|
|
4942
5185
|
template<typename T>
|
|
4943
|
-
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray(size_t count) const
|
|
5186
|
+
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::toArray(size_t count) const
|
|
4944
5187
|
{
|
|
4945
5188
|
if (!this->m_buffer)
|
|
4946
5189
|
{
|
|
@@ -4963,7 +5206,7 @@ namespace Rice4RubyQt6
|
|
|
4963
5206
|
}
|
|
4964
5207
|
|
|
4965
5208
|
template<typename T>
|
|
4966
|
-
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray() const
|
|
5209
|
+
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T> && !std::is_void_v<T>>>::toArray() const
|
|
4967
5210
|
{
|
|
4968
5211
|
return this->toArray(this->m_size);
|
|
4969
5212
|
}
|
|
@@ -5018,8 +5261,8 @@ namespace Rice4RubyQt6
|
|
|
5018
5261
|
}
|
|
5019
5262
|
default:
|
|
5020
5263
|
{
|
|
5021
|
-
detail::
|
|
5022
|
-
std::string typeName =
|
|
5264
|
+
detail::TypeDetail<T> typeDetail;
|
|
5265
|
+
std::string typeName = typeDetail.name();
|
|
5023
5266
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
|
|
5024
5267
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
5025
5268
|
}
|
|
@@ -5103,8 +5346,8 @@ namespace Rice4RubyQt6
|
|
|
5103
5346
|
template<typename T>
|
|
5104
5347
|
inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toString() const
|
|
5105
5348
|
{
|
|
5106
|
-
detail::
|
|
5107
|
-
std::string description = "Buffer<type: " +
|
|
5349
|
+
detail::TypeDetail<T*> typeDetail;
|
|
5350
|
+
std::string description = "Buffer<type: " + typeDetail.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
|
|
5108
5351
|
|
|
5109
5352
|
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
|
5110
5353
|
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
|
@@ -5183,8 +5426,8 @@ namespace Rice4RubyQt6
|
|
|
5183
5426
|
}
|
|
5184
5427
|
default:
|
|
5185
5428
|
{
|
|
5186
|
-
detail::
|
|
5187
|
-
std::string typeName =
|
|
5429
|
+
detail::TypeDetail<T> typeDetail;
|
|
5430
|
+
std::string typeName = typeDetail.name();
|
|
5188
5431
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
|
|
5189
5432
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
5190
5433
|
}
|
|
@@ -5251,6 +5494,57 @@ namespace Rice4RubyQt6
|
|
|
5251
5494
|
return this->bytes(this->m_size);
|
|
5252
5495
|
}
|
|
5253
5496
|
|
|
5497
|
+
// ---- Buffer<void*> -------
|
|
5498
|
+
template<typename T>
|
|
5499
|
+
inline Buffer<T*, std::enable_if_t<std::is_void_v<T>>>::Buffer(T** pointer) : m_buffer(pointer)
|
|
5500
|
+
{
|
|
5501
|
+
}
|
|
5502
|
+
|
|
5503
|
+
template<typename T>
|
|
5504
|
+
inline Buffer<T*, std::enable_if_t<std::is_void_v<T>>>::Buffer(T** pointer, size_t size) : m_size(size), m_buffer(pointer)
|
|
5505
|
+
{
|
|
5506
|
+
}
|
|
5507
|
+
|
|
5508
|
+
template<typename T>
|
|
5509
|
+
inline Buffer<T*, std::enable_if_t<std::is_void_v<T>>>::Buffer(Buffer<T*, std::enable_if_t<std::is_void_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size), m_buffer(other.m_buffer)
|
|
5510
|
+
{
|
|
5511
|
+
other.m_buffer = nullptr;
|
|
5512
|
+
other.m_size = 0;
|
|
5513
|
+
other.m_owner = false;
|
|
5514
|
+
}
|
|
5515
|
+
|
|
5516
|
+
template<typename T>
|
|
5517
|
+
inline Buffer<T*, std::enable_if_t<std::is_void_v<T>>>& Buffer<T*, std::enable_if_t<std::is_void_v<T>>>::operator=(Buffer<T*, std::enable_if_t<std::is_void_v<T>>>&& other)
|
|
5518
|
+
{
|
|
5519
|
+
this->m_buffer = other.m_buffer;
|
|
5520
|
+
this->m_size = other.m_size;
|
|
5521
|
+
this->m_owner = other.m_owner;
|
|
5522
|
+
other.m_buffer = nullptr;
|
|
5523
|
+
other.m_size = 0;
|
|
5524
|
+
other.m_owner = false;
|
|
5525
|
+
|
|
5526
|
+
return *this;
|
|
5527
|
+
}
|
|
5528
|
+
|
|
5529
|
+
template<typename T>
|
|
5530
|
+
inline size_t Buffer<T*, std::enable_if_t<std::is_void_v<T>>>::size() const
|
|
5531
|
+
{
|
|
5532
|
+
return this->m_size;
|
|
5533
|
+
}
|
|
5534
|
+
|
|
5535
|
+
template<typename T>
|
|
5536
|
+
inline T** Buffer<T*, std::enable_if_t<std::is_void_v<T>>>::ptr()
|
|
5537
|
+
{
|
|
5538
|
+
return this->m_buffer;
|
|
5539
|
+
}
|
|
5540
|
+
|
|
5541
|
+
template <typename T>
|
|
5542
|
+
inline T** Buffer<T*, std::enable_if_t<std::is_void_v<T>>>::release()
|
|
5543
|
+
{
|
|
5544
|
+
this->m_owner = false;
|
|
5545
|
+
return this->m_buffer;
|
|
5546
|
+
}
|
|
5547
|
+
|
|
5254
5548
|
// ------ define_buffer ----------
|
|
5255
5549
|
template<typename T>
|
|
5256
5550
|
inline Data_Type<Buffer<T>> define_buffer(std::string klassName)
|
|
@@ -5260,8 +5554,8 @@ namespace Rice4RubyQt6
|
|
|
5260
5554
|
|
|
5261
5555
|
if (klassName.empty())
|
|
5262
5556
|
{
|
|
5263
|
-
detail::
|
|
5264
|
-
klassName =
|
|
5557
|
+
detail::TypeDetail<Buffer_T> typeDetail;
|
|
5558
|
+
klassName = typeDetail.rubyName();
|
|
5265
5559
|
}
|
|
5266
5560
|
|
|
5267
5561
|
Module rb_mRice = define_module("Rice4RubyQt6");
|
|
@@ -5282,6 +5576,14 @@ namespace Rice4RubyQt6
|
|
|
5282
5576
|
define_method("data", &Buffer_T::ptr, ReturnBuffer()).
|
|
5283
5577
|
define_method("release", &Buffer_T::release, ReturnBuffer());
|
|
5284
5578
|
}
|
|
5579
|
+
// void* - minimal wrapper, no Ruby array conversion support
|
|
5580
|
+
else if constexpr (std::is_void_v<detail::intrinsic_type<T>>)
|
|
5581
|
+
{
|
|
5582
|
+
return define_class_under<Buffer_T>(rb_mRice, klassName).
|
|
5583
|
+
define_method("size", &Buffer_T::size).
|
|
5584
|
+
define_method("data", &Buffer_T::ptr, ReturnBuffer()).
|
|
5585
|
+
define_method("release", &Buffer_T::release, ReturnBuffer());
|
|
5586
|
+
}
|
|
5285
5587
|
else
|
|
5286
5588
|
{
|
|
5287
5589
|
Data_Type<Buffer_T> klass = define_class_under<Buffer_T>(rb_mRice, klassName).
|
|
@@ -5297,19 +5599,22 @@ namespace Rice4RubyQt6
|
|
|
5297
5599
|
define_method("data", &Buffer_T::ptr, ReturnBuffer()).
|
|
5298
5600
|
define_method("release", &Buffer_T::release, ReturnBuffer());
|
|
5299
5601
|
|
|
5300
|
-
if constexpr (
|
|
5602
|
+
if constexpr (detail::is_complete_v<detail::intrinsic_type<T>>)
|
|
5301
5603
|
{
|
|
5302
|
-
|
|
5604
|
+
if constexpr (!std::is_pointer_v<T> && !std::is_void_v<T> && !std::is_const_v<T> && std::is_copy_assignable_v<T>)
|
|
5303
5605
|
{
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5606
|
+
klass.define_method("[]=", [](Buffer_T& self, size_t index, T& value) -> void
|
|
5607
|
+
{
|
|
5608
|
+
self[index] = value;
|
|
5609
|
+
});
|
|
5610
|
+
}
|
|
5611
|
+
else if constexpr (std::is_pointer_v<T> && !std::is_const_v<std::remove_pointer_t<T>> && std::is_copy_assignable_v<std::remove_pointer_t<T>>)
|
|
5310
5612
|
{
|
|
5311
|
-
|
|
5312
|
-
|
|
5613
|
+
klass.define_method("[]=", [](Buffer_T& self, size_t index, T value) -> void
|
|
5614
|
+
{
|
|
5615
|
+
*self[index] = *value;
|
|
5616
|
+
});
|
|
5617
|
+
}
|
|
5313
5618
|
}
|
|
5314
5619
|
|
|
5315
5620
|
return klass;
|
|
@@ -5342,8 +5647,8 @@ namespace Rice4RubyQt6
|
|
|
5342
5647
|
|
|
5343
5648
|
if (klassName.empty())
|
|
5344
5649
|
{
|
|
5345
|
-
detail::
|
|
5346
|
-
klassName =
|
|
5650
|
+
detail::TypeDetail<Pointer_T> typeDetail;
|
|
5651
|
+
klassName = typeDetail.rubyName();
|
|
5347
5652
|
}
|
|
5348
5653
|
|
|
5349
5654
|
Module rb_mRice = define_module("Rice4RubyQt6");
|
|
@@ -5789,6 +6094,35 @@ namespace Rice4RubyQt6::detail
|
|
|
5789
6094
|
}
|
|
5790
6095
|
};
|
|
5791
6096
|
|
|
6097
|
+
template<>
|
|
6098
|
+
struct Type<long double>
|
|
6099
|
+
{
|
|
6100
|
+
static bool verify()
|
|
6101
|
+
{
|
|
6102
|
+
return true;
|
|
6103
|
+
}
|
|
6104
|
+
|
|
6105
|
+
static VALUE rubyKlass()
|
|
6106
|
+
{
|
|
6107
|
+
return rb_cFloat;
|
|
6108
|
+
}
|
|
6109
|
+
};
|
|
6110
|
+
|
|
6111
|
+
template<int N>
|
|
6112
|
+
struct Type<long double[N]>
|
|
6113
|
+
{
|
|
6114
|
+
static bool verify()
|
|
6115
|
+
{
|
|
6116
|
+
define_buffer<long double>();
|
|
6117
|
+
return true;
|
|
6118
|
+
}
|
|
6119
|
+
|
|
6120
|
+
static VALUE rubyKlass()
|
|
6121
|
+
{
|
|
6122
|
+
return rb_cString;
|
|
6123
|
+
}
|
|
6124
|
+
};
|
|
6125
|
+
|
|
5792
6126
|
template<>
|
|
5793
6127
|
struct Type<void>
|
|
5794
6128
|
{
|
|
@@ -6087,16 +6421,18 @@ namespace Rice4RubyQt6
|
|
|
6087
6421
|
}
|
|
6088
6422
|
else if (this->arg_ && this->arg_->isOwner())
|
|
6089
6423
|
{
|
|
6090
|
-
// This copies the buffer but does not free it
|
|
6091
|
-
|
|
6092
|
-
//
|
|
6093
|
-
|
|
6424
|
+
// This copies the buffer but does not free it
|
|
6425
|
+
VALUE result = protect(rb_usascii_str_new_cstr, data);
|
|
6426
|
+
// And free the char* since we were told to take "ownership"
|
|
6427
|
+
// TODO - is this a good idea?
|
|
6428
|
+
//free(data);
|
|
6429
|
+
return result;
|
|
6094
6430
|
}
|
|
6095
6431
|
else
|
|
6096
6432
|
{
|
|
6097
6433
|
// Does NOT copy the passed in buffer and does NOT free it when the string is GCed
|
|
6098
|
-
long
|
|
6099
|
-
VALUE result = protect(rb_str_new_static, data,
|
|
6434
|
+
long len = (long)strlen(data);
|
|
6435
|
+
VALUE result = protect(rb_str_new_static, data, len);
|
|
6100
6436
|
// Freeze the object so Ruby can't modify the C string
|
|
6101
6437
|
return rb_obj_freeze(result);
|
|
6102
6438
|
}
|
|
@@ -6286,7 +6622,64 @@ namespace Rice4RubyQt6
|
|
|
6286
6622
|
{
|
|
6287
6623
|
}
|
|
6288
6624
|
|
|
6289
|
-
VALUE convert(const double& native)
|
|
6625
|
+
VALUE convert(const double& native)
|
|
6626
|
+
{
|
|
6627
|
+
return protect(rb_float_new, native);
|
|
6628
|
+
}
|
|
6629
|
+
|
|
6630
|
+
private:
|
|
6631
|
+
Arg* arg_ = nullptr;
|
|
6632
|
+
};
|
|
6633
|
+
|
|
6634
|
+
template<int N>
|
|
6635
|
+
class To_Ruby<double[N]>
|
|
6636
|
+
{
|
|
6637
|
+
public:
|
|
6638
|
+
To_Ruby() = default;
|
|
6639
|
+
|
|
6640
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
6641
|
+
{
|
|
6642
|
+
}
|
|
6643
|
+
|
|
6644
|
+
VALUE convert(double data[N])
|
|
6645
|
+
{
|
|
6646
|
+
Buffer<double> buffer(data, N);
|
|
6647
|
+
Data_Object<Buffer<double>> dataObject(std::move(buffer));
|
|
6648
|
+
return dataObject.value();
|
|
6649
|
+
}
|
|
6650
|
+
private:
|
|
6651
|
+
Arg* arg_ = nullptr;
|
|
6652
|
+
};
|
|
6653
|
+
|
|
6654
|
+
// =========== long double ============
|
|
6655
|
+
template<>
|
|
6656
|
+
class To_Ruby<long double>
|
|
6657
|
+
{
|
|
6658
|
+
public:
|
|
6659
|
+
To_Ruby() = default;
|
|
6660
|
+
|
|
6661
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
6662
|
+
{}
|
|
6663
|
+
|
|
6664
|
+
VALUE convert(const long double& native)
|
|
6665
|
+
{
|
|
6666
|
+
return protect(rb_float_new, native);
|
|
6667
|
+
}
|
|
6668
|
+
|
|
6669
|
+
private:
|
|
6670
|
+
Arg* arg_ = nullptr;
|
|
6671
|
+
};
|
|
6672
|
+
|
|
6673
|
+
template<>
|
|
6674
|
+
class To_Ruby<long double&>
|
|
6675
|
+
{
|
|
6676
|
+
public:
|
|
6677
|
+
To_Ruby() = default;
|
|
6678
|
+
|
|
6679
|
+
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
6680
|
+
{}
|
|
6681
|
+
|
|
6682
|
+
VALUE convert(const long double& native)
|
|
6290
6683
|
{
|
|
6291
6684
|
return protect(rb_float_new, native);
|
|
6292
6685
|
}
|
|
@@ -6296,19 +6689,18 @@ namespace Rice4RubyQt6
|
|
|
6296
6689
|
};
|
|
6297
6690
|
|
|
6298
6691
|
template<int N>
|
|
6299
|
-
class To_Ruby<double[N]>
|
|
6692
|
+
class To_Ruby<long double[N]>
|
|
6300
6693
|
{
|
|
6301
6694
|
public:
|
|
6302
6695
|
To_Ruby() = default;
|
|
6303
6696
|
|
|
6304
6697
|
explicit To_Ruby(Arg* arg) : arg_(arg)
|
|
6305
|
-
{
|
|
6306
|
-
}
|
|
6698
|
+
{}
|
|
6307
6699
|
|
|
6308
|
-
VALUE convert(double data[N])
|
|
6700
|
+
VALUE convert(long double data[N])
|
|
6309
6701
|
{
|
|
6310
|
-
Buffer<double> buffer(data, N);
|
|
6311
|
-
Data_Object<Buffer<double>> dataObject(std::move(buffer));
|
|
6702
|
+
Buffer<long double> buffer(data, N);
|
|
6703
|
+
Data_Object<Buffer<long double>> dataObject(std::move(buffer));
|
|
6312
6704
|
return dataObject.value();
|
|
6313
6705
|
}
|
|
6314
6706
|
private:
|
|
@@ -7040,8 +7432,8 @@ namespace Rice4RubyQt6::detail
|
|
|
7040
7432
|
}
|
|
7041
7433
|
default:
|
|
7042
7434
|
{
|
|
7043
|
-
detail::
|
|
7044
|
-
std::string expected =
|
|
7435
|
+
detail::TypeDetail<Pointer<T>> typeDetail;
|
|
7436
|
+
std::string expected = typeDetail.rubyName();
|
|
7045
7437
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
7046
7438
|
detail::protect(rb_obj_classname, value), expected.c_str());
|
|
7047
7439
|
}
|
|
@@ -7098,8 +7490,8 @@ namespace Rice4RubyQt6::detail
|
|
|
7098
7490
|
}
|
|
7099
7491
|
default:
|
|
7100
7492
|
{
|
|
7101
|
-
detail::
|
|
7102
|
-
std::string expected =
|
|
7493
|
+
detail::TypeDetail<Pointer<T*>> typeDetail;
|
|
7494
|
+
std::string expected = typeDetail.rubyName();
|
|
7103
7495
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
|
|
7104
7496
|
detail::protect(rb_obj_classname, value), expected.c_str());
|
|
7105
7497
|
}
|
|
@@ -7319,13 +7711,25 @@ namespace Rice4RubyQt6::detail
|
|
|
7319
7711
|
}
|
|
7320
7712
|
case RUBY_T_STRING:
|
|
7321
7713
|
{
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7714
|
+
if (this->arg_ && this->arg_->isOwner())
|
|
7715
|
+
{
|
|
7716
|
+
// Warning - the receiver needs to free this string!
|
|
7717
|
+
// TODO - raise an exception if the string has null values?
|
|
7718
|
+
long len = RSTRING_LEN(value);
|
|
7719
|
+
char* result = (char*)malloc(len + 1);
|
|
7720
|
+
memcpy(result, RSTRING_PTR(value), len);
|
|
7721
|
+
result[len] = '\0';
|
|
7722
|
+
return result;
|
|
7723
|
+
}
|
|
7724
|
+
else
|
|
7725
|
+
{
|
|
7726
|
+
// WARNING - this shares the Ruby string memory directly with C++. value really should be frozen.
|
|
7727
|
+
// Maybe we should enforce that? Note the user can always create a Buffer to allocate new memory.
|
|
7728
|
+
return rb_string_value_cstr(&value);
|
|
7729
|
+
}
|
|
7325
7730
|
}
|
|
7326
7731
|
default:
|
|
7327
7732
|
{
|
|
7328
|
-
char* rb_string_value_cstr(volatile VALUE * ptr);
|
|
7329
7733
|
return FromRubyFundamental<char*>::convert(value);
|
|
7330
7734
|
}
|
|
7331
7735
|
}
|
|
@@ -7581,6 +7985,86 @@ namespace Rice4RubyQt6::detail
|
|
|
7581
7985
|
Reference<double> reference_;
|
|
7582
7986
|
};
|
|
7583
7987
|
|
|
7988
|
+
// =========== long double ============
|
|
7989
|
+
template<>
|
|
7990
|
+
class From_Ruby<long double>
|
|
7991
|
+
{
|
|
7992
|
+
public:
|
|
7993
|
+
From_Ruby() = default;
|
|
7994
|
+
|
|
7995
|
+
explicit From_Ruby(Arg* arg) : arg_(arg)
|
|
7996
|
+
{}
|
|
7997
|
+
|
|
7998
|
+
long double is_convertible(VALUE value)
|
|
7999
|
+
{
|
|
8000
|
+
return FromRubyFundamental<long double>::is_convertible(value);
|
|
8001
|
+
}
|
|
8002
|
+
|
|
8003
|
+
long double convert(VALUE value)
|
|
8004
|
+
{
|
|
8005
|
+
return FromRubyFundamental<long double>::convert(value);
|
|
8006
|
+
}
|
|
8007
|
+
|
|
8008
|
+
private:
|
|
8009
|
+
Arg* arg_ = nullptr;
|
|
8010
|
+
};
|
|
8011
|
+
|
|
8012
|
+
template<>
|
|
8013
|
+
class From_Ruby<long double&>
|
|
8014
|
+
{
|
|
8015
|
+
public:
|
|
8016
|
+
using Reference_T = Reference<long double>;
|
|
8017
|
+
|
|
8018
|
+
From_Ruby() = default;
|
|
8019
|
+
|
|
8020
|
+
explicit From_Ruby(Arg* arg) : arg_(arg)
|
|
8021
|
+
{}
|
|
8022
|
+
|
|
8023
|
+
long double is_convertible(VALUE value)
|
|
8024
|
+
{
|
|
8025
|
+
switch (rb_type(value))
|
|
8026
|
+
{
|
|
8027
|
+
case RUBY_T_DATA:
|
|
8028
|
+
{
|
|
8029
|
+
if (Data_Type<Reference_T>::is_descendant(value))
|
|
8030
|
+
{
|
|
8031
|
+
return Convertible::Exact;
|
|
8032
|
+
}
|
|
8033
|
+
[[fallthrough]];
|
|
8034
|
+
}
|
|
8035
|
+
default:
|
|
8036
|
+
{
|
|
8037
|
+
return FromRubyFundamental<long double>::is_convertible(value);
|
|
8038
|
+
}
|
|
8039
|
+
}
|
|
8040
|
+
}
|
|
8041
|
+
|
|
8042
|
+
long double& convert(VALUE value)
|
|
8043
|
+
{
|
|
8044
|
+
switch (rb_type(value))
|
|
8045
|
+
{
|
|
8046
|
+
case RUBY_T_DATA:
|
|
8047
|
+
{
|
|
8048
|
+
if (Data_Type<Reference_T>::is_descendant(value))
|
|
8049
|
+
{
|
|
8050
|
+
Reference_T* reference = unwrap<Reference_T>(value, Data_Type<Reference_T>::ruby_data_type(), false);
|
|
8051
|
+
return reference->get();
|
|
8052
|
+
}
|
|
8053
|
+
[[fallthrough]];
|
|
8054
|
+
}
|
|
8055
|
+
default:
|
|
8056
|
+
{
|
|
8057
|
+
this->reference_ = Reference<long double>(value);
|
|
8058
|
+
return this->reference_.get();
|
|
8059
|
+
}
|
|
8060
|
+
}
|
|
8061
|
+
}
|
|
8062
|
+
|
|
8063
|
+
private:
|
|
8064
|
+
Arg* arg_ = nullptr;
|
|
8065
|
+
Reference<long double> reference_;
|
|
8066
|
+
};
|
|
8067
|
+
|
|
7584
8068
|
// =========== float ============
|
|
7585
8069
|
template<>
|
|
7586
8070
|
class From_Ruby<float>
|
|
@@ -8621,8 +9105,8 @@ namespace Rice4RubyQt6
|
|
|
8621
9105
|
|
|
8622
9106
|
if (klassName.empty())
|
|
8623
9107
|
{
|
|
8624
|
-
detail::
|
|
8625
|
-
klassName =
|
|
9108
|
+
detail::TypeDetail<Reference_T> typeDetail;
|
|
9109
|
+
klassName = typeDetail.rubyName();
|
|
8626
9110
|
}
|
|
8627
9111
|
|
|
8628
9112
|
Module rb_mRice = define_module("Rice4RubyQt6");
|
|
@@ -8668,40 +9152,55 @@ namespace Rice4RubyQt6::detail
|
|
|
8668
9152
|
|
|
8669
9153
|
namespace Rice4RubyQt6::detail
|
|
8670
9154
|
{
|
|
9155
|
+
template <typename T>
|
|
9156
|
+
inline std::type_index TypeRegistry::key()
|
|
9157
|
+
{
|
|
9158
|
+
if constexpr (is_complete_v<T>)
|
|
9159
|
+
{
|
|
9160
|
+
return std::type_index(typeid(T));
|
|
9161
|
+
}
|
|
9162
|
+
else if constexpr (std::is_reference_v<T>)
|
|
9163
|
+
{
|
|
9164
|
+
// For incomplete reference types, strip the reference and use pointer.
|
|
9165
|
+
// Can't form T* when T is a reference type (pointer-to-reference is illegal).
|
|
9166
|
+
return std::type_index(typeid(std::remove_reference_t<T>*));
|
|
9167
|
+
}
|
|
9168
|
+
else
|
|
9169
|
+
{
|
|
9170
|
+
return std::type_index(typeid(T*));
|
|
9171
|
+
}
|
|
9172
|
+
}
|
|
9173
|
+
|
|
8671
9174
|
template <typename T>
|
|
8672
9175
|
inline void TypeRegistry::add(VALUE klass, rb_data_type_t* rbType)
|
|
8673
9176
|
{
|
|
8674
|
-
std::
|
|
8675
|
-
registry_[key] = std::pair(klass, rbType);
|
|
9177
|
+
registry_[key<T>()] = std::pair(klass, rbType);
|
|
8676
9178
|
}
|
|
8677
9179
|
|
|
8678
9180
|
template <typename T>
|
|
8679
9181
|
inline void TypeRegistry::remove()
|
|
8680
9182
|
{
|
|
8681
|
-
|
|
8682
|
-
registry_.erase(key);
|
|
9183
|
+
registry_.erase(key<T>());
|
|
8683
9184
|
}
|
|
8684
9185
|
|
|
8685
9186
|
template <typename T>
|
|
8686
9187
|
inline bool TypeRegistry::isDefined()
|
|
8687
9188
|
{
|
|
8688
|
-
|
|
8689
|
-
auto iter = registry_.find(key);
|
|
9189
|
+
auto iter = registry_.find(key<T>());
|
|
8690
9190
|
return iter != registry_.end();
|
|
8691
9191
|
}
|
|
8692
9192
|
|
|
8693
9193
|
template <typename T>
|
|
8694
9194
|
std::pair<VALUE, rb_data_type_t*> TypeRegistry::getType()
|
|
8695
9195
|
{
|
|
8696
|
-
|
|
8697
|
-
auto iter = registry_.find(key);
|
|
9196
|
+
auto iter = registry_.find(key<T>());
|
|
8698
9197
|
if (iter != registry_.end())
|
|
8699
9198
|
{
|
|
8700
9199
|
return iter->second;
|
|
8701
9200
|
}
|
|
8702
9201
|
else
|
|
8703
9202
|
{
|
|
8704
|
-
this->raiseUnverifiedType(
|
|
9203
|
+
this->raiseUnverifiedType(TypeDetail<T>().name());
|
|
8705
9204
|
// Make compiler happy
|
|
8706
9205
|
return std::make_pair(Qnil, nullptr);
|
|
8707
9206
|
}
|
|
@@ -8716,17 +9215,14 @@ namespace Rice4RubyQt6::detail
|
|
|
8716
9215
|
}
|
|
8717
9216
|
else
|
|
8718
9217
|
{
|
|
8719
|
-
|
|
8720
|
-
std::type_index key(typeInfo);
|
|
8721
|
-
this->unverified_.insert(key);
|
|
9218
|
+
this->unverified_.insert(key<T>());
|
|
8722
9219
|
return false;
|
|
8723
9220
|
}
|
|
8724
9221
|
}
|
|
8725
9222
|
|
|
8726
|
-
inline std::optional<std::pair<VALUE, rb_data_type_t*>> TypeRegistry::lookup(
|
|
9223
|
+
inline std::optional<std::pair<VALUE, rb_data_type_t*>> TypeRegistry::lookup(std::type_index typeIndex)
|
|
8727
9224
|
{
|
|
8728
|
-
|
|
8729
|
-
auto iter = registry_.find(key);
|
|
9225
|
+
auto iter = registry_.find(typeIndex);
|
|
8730
9226
|
|
|
8731
9227
|
if (iter == registry_.end())
|
|
8732
9228
|
{
|
|
@@ -8741,26 +9237,30 @@ namespace Rice4RubyQt6::detail
|
|
|
8741
9237
|
template <typename T>
|
|
8742
9238
|
inline std::pair<VALUE, rb_data_type_t*> TypeRegistry::figureType(const T& object)
|
|
8743
9239
|
{
|
|
8744
|
-
|
|
8745
|
-
std::optional<std::pair<VALUE, rb_data_type_t*>> result = lookup(typeid(object));
|
|
9240
|
+
std::optional<std::pair<VALUE, rb_data_type_t*>> result;
|
|
8746
9241
|
|
|
8747
|
-
if
|
|
9242
|
+
// First check and see if the actual type of the object is registered.
|
|
9243
|
+
// This requires a complete type for typeid to work.
|
|
9244
|
+
if constexpr (is_complete_v<T>)
|
|
8748
9245
|
{
|
|
8749
|
-
|
|
9246
|
+
result = lookup(std::type_index(typeid(object)));
|
|
9247
|
+
|
|
9248
|
+
if (result)
|
|
9249
|
+
{
|
|
9250
|
+
return result.value();
|
|
9251
|
+
}
|
|
8750
9252
|
}
|
|
8751
9253
|
|
|
8752
9254
|
// If not, then we are willing to accept an ancestor class specified by T. This is needed
|
|
8753
9255
|
// to support Directors. Classes inherited from Directors are never actually registered
|
|
8754
9256
|
// with Rice - and what we really want it to return the C++ class they inherit from.
|
|
8755
|
-
|
|
8756
|
-
result = lookup(typeInfo);
|
|
9257
|
+
result = lookup(key<T>());
|
|
8757
9258
|
if (result)
|
|
8758
9259
|
{
|
|
8759
9260
|
return result.value();
|
|
8760
9261
|
}
|
|
8761
9262
|
|
|
8762
|
-
|
|
8763
|
-
raiseUnverifiedType(typeIndexParser.name());
|
|
9263
|
+
raiseUnverifiedType(TypeDetail<T>().name());
|
|
8764
9264
|
|
|
8765
9265
|
// Make the compiler happy
|
|
8766
9266
|
return std::pair<VALUE, rb_data_type_t*>(Qnil, nullptr);
|
|
@@ -8794,8 +9294,8 @@ namespace Rice4RubyQt6::detail
|
|
|
8794
9294
|
|
|
8795
9295
|
for (const std::type_index& typeIndex : this->unverified_)
|
|
8796
9296
|
{
|
|
8797
|
-
detail::TypeIndexParser
|
|
8798
|
-
stream << " " <<
|
|
9297
|
+
detail::TypeIndexParser typeDetail(typeIndex);
|
|
9298
|
+
stream << " " << typeDetail.name() << "\n";
|
|
8799
9299
|
}
|
|
8800
9300
|
|
|
8801
9301
|
throw std::invalid_argument(stream.str());
|
|
@@ -8831,39 +9331,26 @@ namespace Rice4RubyQt6::detail
|
|
|
8831
9331
|
namespace Rice4RubyQt6::detail
|
|
8832
9332
|
{
|
|
8833
9333
|
template <typename T>
|
|
8834
|
-
inline VALUE InstanceRegistry::lookup(T
|
|
8835
|
-
{
|
|
8836
|
-
return this->lookup((void*)&cppInstance);
|
|
8837
|
-
}
|
|
8838
|
-
|
|
8839
|
-
template <typename T>
|
|
8840
|
-
inline VALUE InstanceRegistry::lookup(T* cppInstance)
|
|
8841
|
-
{
|
|
8842
|
-
return this->lookup((void*)cppInstance);
|
|
8843
|
-
}
|
|
8844
|
-
|
|
8845
|
-
inline VALUE InstanceRegistry::lookup(void* cppInstance)
|
|
9334
|
+
inline VALUE InstanceRegistry::lookup(T* cppInstance, bool isOwner)
|
|
8846
9335
|
{
|
|
8847
|
-
if (!this->
|
|
8848
|
-
return Qnil;
|
|
8849
|
-
|
|
8850
|
-
auto it = this->objectMap_.find(cppInstance);
|
|
8851
|
-
if (it != this->objectMap_.end())
|
|
8852
|
-
{
|
|
8853
|
-
return it->second;
|
|
8854
|
-
}
|
|
8855
|
-
else
|
|
9336
|
+
if (!this->shouldTrack(isOwner))
|
|
8856
9337
|
{
|
|
8857
9338
|
return Qnil;
|
|
8858
9339
|
}
|
|
9340
|
+
|
|
9341
|
+
auto it = this->objectMap_.find((void*)cppInstance);
|
|
9342
|
+
return it != this->objectMap_.end() ? it->second : Qnil;
|
|
8859
9343
|
}
|
|
8860
9344
|
|
|
8861
|
-
|
|
9345
|
+
template <typename T>
|
|
9346
|
+
inline void InstanceRegistry::add(T* cppInstance, VALUE rubyInstance, bool isOwner)
|
|
8862
9347
|
{
|
|
8863
|
-
if (this->
|
|
9348
|
+
if (!this->shouldTrack(isOwner))
|
|
8864
9349
|
{
|
|
8865
|
-
|
|
9350
|
+
return;
|
|
8866
9351
|
}
|
|
9352
|
+
|
|
9353
|
+
this->objectMap_[(void*)cppInstance] = rubyInstance;
|
|
8867
9354
|
}
|
|
8868
9355
|
|
|
8869
9356
|
inline void InstanceRegistry::remove(void* cppInstance)
|
|
@@ -8875,7 +9362,22 @@ namespace Rice4RubyQt6::detail
|
|
|
8875
9362
|
{
|
|
8876
9363
|
this->objectMap_.clear();
|
|
8877
9364
|
}
|
|
8878
|
-
|
|
9365
|
+
|
|
9366
|
+
inline bool InstanceRegistry::shouldTrack(bool isOwner) const
|
|
9367
|
+
{
|
|
9368
|
+
switch (this->mode)
|
|
9369
|
+
{
|
|
9370
|
+
case Mode::Off:
|
|
9371
|
+
return false;
|
|
9372
|
+
case Mode::Owned:
|
|
9373
|
+
return isOwner;
|
|
9374
|
+
case Mode::All:
|
|
9375
|
+
return true;
|
|
9376
|
+
default:
|
|
9377
|
+
return false;
|
|
9378
|
+
}
|
|
9379
|
+
}
|
|
9380
|
+
}
|
|
8879
9381
|
|
|
8880
9382
|
// ========= DefaultHandler.ipp =========
|
|
8881
9383
|
namespace Rice4RubyQt6::detail
|
|
@@ -9048,12 +9550,6 @@ namespace Rice4RubyQt6::detail
|
|
|
9048
9550
|
|
|
9049
9551
|
|
|
9050
9552
|
// ========= Type.ipp =========
|
|
9051
|
-
#ifdef __GNUC__
|
|
9052
|
-
#include <cxxabi.h>
|
|
9053
|
-
#include <cstdlib>
|
|
9054
|
-
#include <cstring>
|
|
9055
|
-
#endif
|
|
9056
|
-
|
|
9057
9553
|
// Rice saves types either as the intrinsic type (MyObject) or pointer (MyObject*).
|
|
9058
9554
|
// It strips out references, const and volatile to avoid an explosion of template classes.
|
|
9059
9555
|
// Pointers are used for C function pointers used in callbacks and for the Buffer class.
|
|
@@ -9090,6 +9586,19 @@ namespace Rice4RubyQt6::detail
|
|
|
9090
9586
|
return Type<T>::verify();
|
|
9091
9587
|
}
|
|
9092
9588
|
|
|
9589
|
+
template <typename T, int N>
|
|
9590
|
+
inline bool Type<T[N]>::verify()
|
|
9591
|
+
{
|
|
9592
|
+
return Type<T>::verify();
|
|
9593
|
+
}
|
|
9594
|
+
|
|
9595
|
+
template <typename T, int N>
|
|
9596
|
+
inline VALUE Type<T[N]>::rubyKlass()
|
|
9597
|
+
{
|
|
9598
|
+
detail::TypeDetail<Pointer<T>> typeDetail;
|
|
9599
|
+
return typeDetail.rubyKlass();
|
|
9600
|
+
}
|
|
9601
|
+
|
|
9093
9602
|
template<typename T>
|
|
9094
9603
|
void verifyType()
|
|
9095
9604
|
{
|
|
@@ -9108,19 +9617,17 @@ namespace Rice4RubyQt6::detail
|
|
|
9108
9617
|
std::make_index_sequence<std::tuple_size_v<Tuple_T>> indexes;
|
|
9109
9618
|
verifyTypesImpl<Tuple_T>(indexes);
|
|
9110
9619
|
}
|
|
9620
|
+
}
|
|
9111
9621
|
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
template<typename T>
|
|
9120
|
-
struct has_ruby_klass<T, std::void_t<decltype(T::rubyKlass())>> : std::true_type
|
|
9121
|
-
{
|
|
9122
|
-
};
|
|
9622
|
+
// ========= TypeIndexParser.ipp =========
|
|
9623
|
+
#ifdef __GNUC__
|
|
9624
|
+
#include <cxxabi.h>
|
|
9625
|
+
#include <cstdlib>
|
|
9626
|
+
#include <cstring>
|
|
9627
|
+
#endif
|
|
9123
9628
|
|
|
9629
|
+
namespace Rice4RubyQt6::detail
|
|
9630
|
+
{
|
|
9124
9631
|
// ---------- TypeIndexParser ------------
|
|
9125
9632
|
inline TypeIndexParser::TypeIndexParser(const std::type_index& typeIndex, bool isFundamental) :
|
|
9126
9633
|
typeIndex_(typeIndex), isFundamental_(isFundamental)
|
|
@@ -9151,9 +9658,9 @@ namespace Rice4RubyQt6::detail
|
|
|
9151
9658
|
}
|
|
9152
9659
|
|
|
9153
9660
|
// Find text inside of < > taking into account nested groups.
|
|
9154
|
-
//
|
|
9661
|
+
//
|
|
9155
9662
|
// Example:
|
|
9156
|
-
//
|
|
9663
|
+
//
|
|
9157
9664
|
// std::vector<std::vector<int>, std::allocator<std::vector, std::allocator<int>>>
|
|
9158
9665
|
inline std::string TypeIndexParser::findGroup(std::string& string, size_t offset)
|
|
9159
9666
|
{
|
|
@@ -9267,10 +9774,18 @@ namespace Rice4RubyQt6::detail
|
|
|
9267
9774
|
std::regex ptrRegex = std::regex(R"(\s+\*)");
|
|
9268
9775
|
base = std::regex_replace(base, ptrRegex, "*");
|
|
9269
9776
|
|
|
9777
|
+
// Remove spaces before left parentheses
|
|
9778
|
+
std::regex parenRegex = std::regex(R"(\s+\()");
|
|
9779
|
+
base = std::regex_replace(base, parenRegex, "(");
|
|
9780
|
+
|
|
9270
9781
|
// Remove __ptr64
|
|
9271
9782
|
std::regex ptr64Regex(R"(\s*__ptr64\s*)");
|
|
9272
9783
|
base = std::regex_replace(base, ptr64Regex, "");
|
|
9273
9784
|
|
|
9785
|
+
// Remove calling conventions (__cdecl, __stdcall, __fastcall, etc.)
|
|
9786
|
+
std::regex callingConventionRegex(R"(\s*__cdecl|__stdcall|__fastcall)");
|
|
9787
|
+
base = std::regex_replace(base, callingConventionRegex, "");
|
|
9788
|
+
|
|
9274
9789
|
// Replace " >" with ">"
|
|
9275
9790
|
std::regex trailingAngleBracketSpaceRegex = std::regex(R"(\s+>)");
|
|
9276
9791
|
replaceAll(base, trailingAngleBracketSpaceRegex, ">");
|
|
@@ -9342,6 +9857,16 @@ namespace Rice4RubyQt6::detail
|
|
|
9342
9857
|
//replaceAll(base, greaterThanRegex, "≻");
|
|
9343
9858
|
this->replaceAll(base, greaterThanRegex, "\u227B");
|
|
9344
9859
|
|
|
9860
|
+
// Replace ( with Unicode Character (U+2768) - Medium Left Parenthesis Ornament
|
|
9861
|
+
// This happens in std::function
|
|
9862
|
+
auto leftParenRegex = std::regex(R"(\()");
|
|
9863
|
+
this->replaceAll(base, leftParenRegex, "\u2768");
|
|
9864
|
+
|
|
9865
|
+
// Replace ) with Unicode Character (U+2769) - Medium Right Parenthesis Ornament
|
|
9866
|
+
// This happens in std::function
|
|
9867
|
+
auto rightParenRegex = std::regex(R"(\))");
|
|
9868
|
+
this->replaceAll(base, rightParenRegex, "\u2769");
|
|
9869
|
+
|
|
9345
9870
|
// Replace , with Unicode Character (U+066C) - Arabic Thousands Separator
|
|
9346
9871
|
auto commaRegex = std::regex(R"(,\s*)");
|
|
9347
9872
|
this->replaceAll(base, commaRegex, "\u201A");
|
|
@@ -9359,7 +9884,7 @@ namespace Rice4RubyQt6::detail
|
|
|
9359
9884
|
while (std::regex_search(content, match, regex))
|
|
9360
9885
|
{
|
|
9361
9886
|
std::string replacement = match[1];
|
|
9362
|
-
std::transform(replacement.begin(), replacement.end(), replacement.begin(),
|
|
9887
|
+
std::transform(replacement.begin(), replacement.end(), replacement.begin(),
|
|
9363
9888
|
[](unsigned char c) -> char
|
|
9364
9889
|
{
|
|
9365
9890
|
return static_cast<char>(std::toupper(c));
|
|
@@ -9368,9 +9893,53 @@ namespace Rice4RubyQt6::detail
|
|
|
9368
9893
|
}
|
|
9369
9894
|
}
|
|
9370
9895
|
|
|
9371
|
-
// ----------
|
|
9896
|
+
// ---------- TypeDetail<T> ------------
|
|
9897
|
+
template<typename T>
|
|
9898
|
+
inline std::type_index TypeDetail<T>::typeIndex()
|
|
9899
|
+
{
|
|
9900
|
+
if constexpr (is_complete_v<T>)
|
|
9901
|
+
{
|
|
9902
|
+
return typeid(T);
|
|
9903
|
+
}
|
|
9904
|
+
else if constexpr (std::is_reference_v<T>)
|
|
9905
|
+
{
|
|
9906
|
+
// For incomplete reference types, strip the reference and use pointer.
|
|
9907
|
+
// Can't use typeid(T&) because it still requires complete type on MSVC.
|
|
9908
|
+
return typeid(std::remove_reference_t<T>*);
|
|
9909
|
+
}
|
|
9910
|
+
else
|
|
9911
|
+
{
|
|
9912
|
+
return typeid(T*);
|
|
9913
|
+
}
|
|
9914
|
+
}
|
|
9915
|
+
|
|
9916
|
+
template<typename T>
|
|
9917
|
+
inline bool TypeDetail<T>::isFundamental()
|
|
9918
|
+
{
|
|
9919
|
+
if constexpr (is_complete_v<T>)
|
|
9920
|
+
{
|
|
9921
|
+
return std::is_fundamental_v<intrinsic_type<T>>;
|
|
9922
|
+
}
|
|
9923
|
+
else
|
|
9924
|
+
{
|
|
9925
|
+
return false;
|
|
9926
|
+
}
|
|
9927
|
+
}
|
|
9928
|
+
|
|
9929
|
+
template<typename T>
|
|
9930
|
+
inline std::string TypeDetail<T>::name()
|
|
9931
|
+
{
|
|
9932
|
+
return this->typeIndexParser_.name();
|
|
9933
|
+
}
|
|
9934
|
+
|
|
9935
|
+
template<typename T>
|
|
9936
|
+
inline std::string TypeDetail<T>::simplifiedName()
|
|
9937
|
+
{
|
|
9938
|
+
return this->typeIndexParser_.simplifiedName();
|
|
9939
|
+
}
|
|
9940
|
+
|
|
9372
9941
|
template<typename T>
|
|
9373
|
-
inline std::string
|
|
9942
|
+
inline std::string TypeDetail<T>::rubyTypeName()
|
|
9374
9943
|
{
|
|
9375
9944
|
using Intrinsic_T = detail::intrinsic_type<T>;
|
|
9376
9945
|
|
|
@@ -9384,20 +9953,20 @@ namespace Rice4RubyQt6::detail
|
|
|
9384
9953
|
}
|
|
9385
9954
|
else
|
|
9386
9955
|
{
|
|
9387
|
-
|
|
9388
|
-
return
|
|
9956
|
+
TypeDetail<Intrinsic_T> typeDetail;
|
|
9957
|
+
return typeDetail.simplifiedName();
|
|
9389
9958
|
}
|
|
9390
9959
|
}
|
|
9391
9960
|
|
|
9392
9961
|
template<typename T>
|
|
9393
|
-
inline std::string
|
|
9962
|
+
inline std::string TypeDetail<T>::rubyName()
|
|
9394
9963
|
{
|
|
9395
9964
|
std::string base = this->rubyTypeName();
|
|
9396
9965
|
return this->typeIndexParser_.rubyName(base);
|
|
9397
9966
|
}
|
|
9398
9967
|
|
|
9399
9968
|
template<typename T>
|
|
9400
|
-
inline VALUE
|
|
9969
|
+
inline VALUE TypeDetail<T>::rubyKlass()
|
|
9401
9970
|
{
|
|
9402
9971
|
using Type_T = Type<std::remove_reference_t<detail::remove_cv_recursive_t<T>>>;
|
|
9403
9972
|
using Intrinsic_T = detail::intrinsic_type<T>;
|
|
@@ -9408,7 +9977,7 @@ namespace Rice4RubyQt6::detail
|
|
|
9408
9977
|
}
|
|
9409
9978
|
else if constexpr (std::is_fundamental_v<Intrinsic_T> && std::is_pointer_v<T>)
|
|
9410
9979
|
{
|
|
9411
|
-
|
|
9980
|
+
using Pointer_T = Pointer<std::remove_pointer_t<remove_cv_recursive_t<T>>>;
|
|
9412
9981
|
std::pair<VALUE, rb_data_type_t*> pair = Registries::instance.types.getType<Pointer_T>();
|
|
9413
9982
|
return pair.first;
|
|
9414
9983
|
}
|
|
@@ -9419,6 +9988,7 @@ namespace Rice4RubyQt6::detail
|
|
|
9419
9988
|
}
|
|
9420
9989
|
}
|
|
9421
9990
|
}
|
|
9991
|
+
|
|
9422
9992
|
// Code for Ruby to call C++
|
|
9423
9993
|
|
|
9424
9994
|
// ========= Exception.ipp =========
|
|
@@ -9456,7 +10026,8 @@ namespace Rice4RubyQt6
|
|
|
9456
10026
|
#endif
|
|
9457
10027
|
|
|
9458
10028
|
// Now create the Ruby exception
|
|
9459
|
-
|
|
10029
|
+
VALUE exception = detail::protect(rb_exc_new2, exceptionClass, this->message_.c_str());
|
|
10030
|
+
this->exception_ = Pin(exception);
|
|
9460
10031
|
}
|
|
9461
10032
|
|
|
9462
10033
|
inline char const* Exception::what() const noexcept
|
|
@@ -9465,7 +10036,7 @@ namespace Rice4RubyQt6
|
|
|
9465
10036
|
{
|
|
9466
10037
|
// This isn't protected because if it fails then either we could eat the exception
|
|
9467
10038
|
// (not good) or crash the program (better)
|
|
9468
|
-
VALUE rubyMessage = rb_funcall(this->exception_, rb_intern("message"), 0);
|
|
10039
|
+
VALUE rubyMessage = rb_funcall(this->exception_.value(), rb_intern("message"), 0);
|
|
9469
10040
|
this->message_ = std::string(RSTRING_PTR(rubyMessage), RSTRING_LEN(rubyMessage));
|
|
9470
10041
|
}
|
|
9471
10042
|
return this->message_.c_str();
|
|
@@ -9473,12 +10044,12 @@ namespace Rice4RubyQt6
|
|
|
9473
10044
|
|
|
9474
10045
|
inline VALUE Exception::class_of() const
|
|
9475
10046
|
{
|
|
9476
|
-
return detail::protect(rb_class_of, this->exception_);
|
|
10047
|
+
return detail::protect(rb_class_of, this->exception_.value());
|
|
9477
10048
|
}
|
|
9478
10049
|
|
|
9479
10050
|
inline VALUE Exception::value() const
|
|
9480
10051
|
{
|
|
9481
|
-
return this->exception_;
|
|
10052
|
+
return this->exception_.value();
|
|
9482
10053
|
}
|
|
9483
10054
|
}
|
|
9484
10055
|
|
|
@@ -9503,6 +10074,9 @@ namespace Rice4RubyQt6::detail
|
|
|
9503
10074
|
template <typename Callable_T>
|
|
9504
10075
|
auto cpp_protect(Callable_T&& func)
|
|
9505
10076
|
{
|
|
10077
|
+
VALUE excValue = Qnil;
|
|
10078
|
+
int jumpTag = 0;
|
|
10079
|
+
|
|
9506
10080
|
try
|
|
9507
10081
|
{
|
|
9508
10082
|
return func();
|
|
@@ -9516,69 +10090,76 @@ namespace Rice4RubyQt6::detail
|
|
|
9516
10090
|
}
|
|
9517
10091
|
catch (::Rice4RubyQt6::Exception const& ex)
|
|
9518
10092
|
{
|
|
9519
|
-
|
|
10093
|
+
excValue = ex.value();
|
|
9520
10094
|
}
|
|
9521
10095
|
catch (::Rice4RubyQt6::JumpException const& ex)
|
|
9522
10096
|
{
|
|
9523
|
-
|
|
10097
|
+
jumpTag = ex.tag;
|
|
9524
10098
|
}
|
|
9525
10099
|
catch (std::bad_alloc const& ex)
|
|
9526
10100
|
{
|
|
9527
10101
|
/* This won't work quite right if the rb_exc_new2 fails; not
|
|
9528
10102
|
much we can do about that, since Ruby doesn't give us access
|
|
9529
10103
|
to a pre-allocated NoMemoryError object */
|
|
9530
|
-
|
|
10104
|
+
excValue = rb_exc_new2(rb_eNoMemError, ex.what());
|
|
9531
10105
|
}
|
|
9532
10106
|
catch (std::domain_error const& ex)
|
|
9533
10107
|
{
|
|
9534
|
-
|
|
10108
|
+
excValue = rb_exc_new2(rb_eFloatDomainError, ex.what());
|
|
9535
10109
|
}
|
|
9536
10110
|
catch (std::invalid_argument const& ex)
|
|
9537
10111
|
{
|
|
9538
|
-
|
|
10112
|
+
excValue = rb_exc_new2(rb_eArgError, ex.what());
|
|
9539
10113
|
}
|
|
9540
10114
|
catch (fs::filesystem_error const& ex)
|
|
9541
10115
|
{
|
|
9542
|
-
|
|
10116
|
+
excValue = rb_exc_new2(rb_eIOError, ex.what());
|
|
9543
10117
|
}
|
|
9544
10118
|
catch (std::length_error const& ex)
|
|
9545
10119
|
{
|
|
9546
|
-
|
|
10120
|
+
excValue = rb_exc_new2(rb_eIndexError, ex.what());
|
|
9547
10121
|
}
|
|
9548
10122
|
catch (std::out_of_range const& ex)
|
|
9549
10123
|
{
|
|
9550
|
-
|
|
10124
|
+
excValue = rb_exc_new2(rb_eIndexError, ex.what());
|
|
9551
10125
|
}
|
|
9552
10126
|
catch (std::overflow_error const& ex)
|
|
9553
10127
|
{
|
|
9554
|
-
|
|
10128
|
+
excValue = rb_exc_new2(rb_eRangeError, ex.what());
|
|
9555
10129
|
}
|
|
9556
10130
|
catch (std::range_error const& ex)
|
|
9557
10131
|
{
|
|
9558
|
-
|
|
10132
|
+
excValue = rb_exc_new2(rb_eRangeError, ex.what());
|
|
9559
10133
|
}
|
|
9560
10134
|
catch (std::regex_error const& ex)
|
|
9561
10135
|
{
|
|
9562
|
-
|
|
10136
|
+
excValue = rb_exc_new2(rb_eRegexpError, ex.what());
|
|
9563
10137
|
}
|
|
9564
10138
|
catch (std::system_error const& ex)
|
|
9565
10139
|
{
|
|
9566
|
-
|
|
10140
|
+
excValue = rb_exc_new2(rb_eSystemCallError, ex.what());
|
|
9567
10141
|
}
|
|
9568
10142
|
catch (std::underflow_error const& ex)
|
|
9569
10143
|
{
|
|
9570
|
-
|
|
10144
|
+
excValue = rb_exc_new2(rb_eRangeError, ex.what());
|
|
9571
10145
|
}
|
|
9572
10146
|
catch (std::exception const& ex)
|
|
9573
10147
|
{
|
|
9574
|
-
|
|
10148
|
+
excValue = rb_exc_new2(rb_eRuntimeError, ex.what());
|
|
9575
10149
|
}
|
|
9576
10150
|
catch (...)
|
|
9577
10151
|
{
|
|
9578
|
-
|
|
10152
|
+
excValue = rb_exc_new2(rb_eRuntimeError, "Unknown C++ exception thrown");
|
|
9579
10153
|
}
|
|
9580
|
-
throw std::runtime_error("Should never get here - just making compilers happy");
|
|
9581
10154
|
}
|
|
10155
|
+
// All C++ exception objects and the handler are now destroyed.
|
|
10156
|
+
// It is safe to call rb_jump_tag/rb_exc_raise which use longjmp.
|
|
10157
|
+
if (jumpTag)
|
|
10158
|
+
rb_jump_tag(jumpTag);
|
|
10159
|
+
else
|
|
10160
|
+
rb_exc_raise(excValue);
|
|
10161
|
+
|
|
10162
|
+
throw std::runtime_error("Should never get here - just making compilers happy");
|
|
9582
10163
|
}
|
|
9583
10164
|
}
|
|
9584
10165
|
|
|
@@ -9621,6 +10202,16 @@ namespace Rice4RubyQt6::detail
|
|
|
9621
10202
|
this->keepAlive_.push_back(value);
|
|
9622
10203
|
}
|
|
9623
10204
|
|
|
10205
|
+
inline const std::vector<VALUE>& WrapperBase::getKeepAlive() const
|
|
10206
|
+
{
|
|
10207
|
+
return this->keepAlive_;
|
|
10208
|
+
}
|
|
10209
|
+
|
|
10210
|
+
inline void WrapperBase::setKeepAlive(const std::vector<VALUE>& keepAlive)
|
|
10211
|
+
{
|
|
10212
|
+
this->keepAlive_ = keepAlive;
|
|
10213
|
+
}
|
|
10214
|
+
|
|
9624
10215
|
inline void WrapperBase::setOwner(bool value)
|
|
9625
10216
|
{
|
|
9626
10217
|
this->isOwner_ = value;
|
|
@@ -9638,12 +10229,6 @@ namespace Rice4RubyQt6::detail
|
|
|
9638
10229
|
{
|
|
9639
10230
|
}
|
|
9640
10231
|
|
|
9641
|
-
template <typename T>
|
|
9642
|
-
inline Wrapper<T>::~Wrapper()
|
|
9643
|
-
{
|
|
9644
|
-
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
9645
|
-
}
|
|
9646
|
-
|
|
9647
10232
|
template <typename T>
|
|
9648
10233
|
inline void* Wrapper<T>::get(rb_data_type_t* requestedType)
|
|
9649
10234
|
{
|
|
@@ -9700,11 +10285,14 @@ namespace Rice4RubyQt6::detail
|
|
|
9700
10285
|
{
|
|
9701
10286
|
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
9702
10287
|
|
|
9703
|
-
if constexpr (
|
|
10288
|
+
if constexpr (is_complete_v<T>)
|
|
9704
10289
|
{
|
|
9705
|
-
if (
|
|
10290
|
+
if constexpr (std::is_destructible_v<T>)
|
|
9706
10291
|
{
|
|
9707
|
-
|
|
10292
|
+
if (this->isOwner_)
|
|
10293
|
+
{
|
|
10294
|
+
delete this->data_;
|
|
10295
|
+
}
|
|
9708
10296
|
}
|
|
9709
10297
|
}
|
|
9710
10298
|
}
|
|
@@ -9737,11 +10325,14 @@ namespace Rice4RubyQt6::detail
|
|
|
9737
10325
|
{
|
|
9738
10326
|
Registries::instance.instances.remove(this->get(this->rb_data_type_));
|
|
9739
10327
|
|
|
9740
|
-
if constexpr (
|
|
10328
|
+
if constexpr (is_complete_v<T>)
|
|
9741
10329
|
{
|
|
9742
|
-
if (
|
|
10330
|
+
if constexpr (std::is_destructible_v<T>)
|
|
9743
10331
|
{
|
|
9744
|
-
|
|
10332
|
+
if (this->isOwner_)
|
|
10333
|
+
{
|
|
10334
|
+
delete this->data_;
|
|
10335
|
+
}
|
|
9745
10336
|
}
|
|
9746
10337
|
}
|
|
9747
10338
|
}
|
|
@@ -9763,68 +10354,83 @@ namespace Rice4RubyQt6::detail
|
|
|
9763
10354
|
|
|
9764
10355
|
// ---- Helper Functions -------
|
|
9765
10356
|
template <typename T>
|
|
9766
|
-
inline VALUE
|
|
10357
|
+
inline VALUE wrapLvalue(VALUE klass, rb_data_type_t* rb_data_type, T& data)
|
|
9767
10358
|
{
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
return result;
|
|
10359
|
+
WrapperBase* wrapper = new Wrapper<T>(rb_data_type, data);
|
|
10360
|
+
return TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
10361
|
+
}
|
|
9772
10362
|
|
|
9773
|
-
|
|
10363
|
+
template <typename T>
|
|
10364
|
+
inline VALUE wrapRvalue(VALUE klass, rb_data_type_t* rb_data_type, T& data)
|
|
10365
|
+
{
|
|
10366
|
+
WrapperBase* wrapper = new Wrapper<T>(rb_data_type, std::move(data));
|
|
10367
|
+
return TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
10368
|
+
}
|
|
9774
10369
|
|
|
9775
|
-
|
|
9776
|
-
|
|
10370
|
+
template <typename T>
|
|
10371
|
+
inline VALUE wrapReference(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner)
|
|
10372
|
+
{
|
|
10373
|
+
VALUE result = Registries::instance.instances.lookup(&data, isOwner);
|
|
10374
|
+
if (result == Qnil)
|
|
9777
10375
|
{
|
|
9778
|
-
wrapper = new Wrapper<T&>(rb_data_type, data);
|
|
10376
|
+
WrapperBase* wrapper = new Wrapper<T&>(rb_data_type, data);
|
|
9779
10377
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
10378
|
+
Registries::instance.instances.add(&data, result, isOwner);
|
|
9780
10379
|
}
|
|
10380
|
+
return result;
|
|
10381
|
+
}
|
|
9781
10382
|
|
|
10383
|
+
template <typename T>
|
|
10384
|
+
inline VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner)
|
|
10385
|
+
{
|
|
10386
|
+
// Incomplete types can't be copied/moved, just wrap as reference
|
|
10387
|
+
if constexpr (!is_complete_v<T>)
|
|
10388
|
+
{
|
|
10389
|
+
return wrapReference(klass, rb_data_type, data, isOwner);
|
|
10390
|
+
}
|
|
10391
|
+
// If Ruby is not the owner then wrap the reference
|
|
10392
|
+
else if (!isOwner)
|
|
10393
|
+
{
|
|
10394
|
+
return wrapReference(klass, rb_data_type, data, isOwner);
|
|
10395
|
+
}
|
|
9782
10396
|
// std::is_copy_constructible_v<std::vector<std::unique_ptr<T>>>> returns true. Sigh.
|
|
9783
10397
|
else if constexpr (detail::is_std_vector_v<T>)
|
|
9784
10398
|
{
|
|
9785
10399
|
if constexpr (std::is_copy_constructible_v<typename T::value_type>)
|
|
9786
10400
|
{
|
|
9787
|
-
|
|
9788
|
-
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
10401
|
+
return wrapLvalue(klass, rb_data_type, data);
|
|
9789
10402
|
}
|
|
9790
10403
|
else
|
|
9791
10404
|
{
|
|
9792
|
-
|
|
9793
|
-
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
10405
|
+
return wrapRvalue(klass, rb_data_type, data);
|
|
9794
10406
|
}
|
|
9795
10407
|
}
|
|
9796
10408
|
|
|
9797
10409
|
// Ruby is the owner so copy data
|
|
9798
10410
|
else if constexpr (std::is_copy_constructible_v<T>)
|
|
9799
10411
|
{
|
|
9800
|
-
|
|
9801
|
-
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
10412
|
+
return wrapLvalue(klass, rb_data_type, data);
|
|
9802
10413
|
}
|
|
9803
10414
|
|
|
9804
10415
|
// Ruby is the owner so move data
|
|
9805
10416
|
else if constexpr (std::is_move_constructible_v<T>)
|
|
9806
10417
|
{
|
|
9807
|
-
|
|
9808
|
-
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
10418
|
+
return wrapRvalue(klass, rb_data_type, data);
|
|
9809
10419
|
}
|
|
9810
10420
|
|
|
9811
10421
|
else
|
|
9812
10422
|
{
|
|
9813
|
-
detail::
|
|
10423
|
+
detail::TypeDetail<T> typeDetail;
|
|
9814
10424
|
std::string message = "Rice was directed to take ownership of a C++ object but it does not have an accessible copy or move constructor. Type: " +
|
|
9815
|
-
|
|
10425
|
+
typeDetail.name();
|
|
9816
10426
|
throw std::runtime_error(message);
|
|
9817
10427
|
}
|
|
9818
|
-
|
|
9819
|
-
Registries::instance.instances.add(wrapper->get(rb_data_type), result);
|
|
9820
|
-
|
|
9821
|
-
return result;
|
|
9822
10428
|
};
|
|
9823
10429
|
|
|
9824
10430
|
template <typename T>
|
|
9825
10431
|
inline VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T* data, bool isOwner)
|
|
9826
10432
|
{
|
|
9827
|
-
VALUE result = Registries::instance.instances.lookup(data);
|
|
10433
|
+
VALUE result = Registries::instance.instances.lookup(data, isOwner);
|
|
9828
10434
|
|
|
9829
10435
|
if (result != Qnil)
|
|
9830
10436
|
return result;
|
|
@@ -9832,7 +10438,7 @@ namespace Rice4RubyQt6::detail
|
|
|
9832
10438
|
WrapperBase* wrapper = new Wrapper<T*>(rb_data_type, data, isOwner);
|
|
9833
10439
|
result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
|
|
9834
10440
|
|
|
9835
|
-
Registries::instance.instances.add(
|
|
10441
|
+
Registries::instance.instances.add(data, result, isOwner);
|
|
9836
10442
|
return result;
|
|
9837
10443
|
};
|
|
9838
10444
|
|
|
@@ -9846,6 +10452,12 @@ namespace Rice4RubyQt6::detail
|
|
|
9846
10452
|
throw std::runtime_error(message);
|
|
9847
10453
|
}
|
|
9848
10454
|
|
|
10455
|
+
if (protect(rb_obj_is_kind_of, value, rb_cProc))
|
|
10456
|
+
{
|
|
10457
|
+
std::string message = "The Ruby object is a proc or lambda and does not wrap a C++ object";
|
|
10458
|
+
throw std::runtime_error(message);
|
|
10459
|
+
}
|
|
10460
|
+
|
|
9849
10461
|
WrapperBase* wrapper = static_cast<WrapperBase*>(RTYPEDDATA_DATA(value));
|
|
9850
10462
|
|
|
9851
10463
|
if (wrapper == nullptr)
|
|
@@ -9896,7 +10508,7 @@ namespace Rice4RubyQt6::detail
|
|
|
9896
10508
|
}
|
|
9897
10509
|
|
|
9898
10510
|
template <typename T>
|
|
9899
|
-
inline Wrapper<T*>* wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data)
|
|
10511
|
+
inline Wrapper<T*>* wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data, VALUE source)
|
|
9900
10512
|
{
|
|
9901
10513
|
using Wrapper_T = Wrapper<T*>;
|
|
9902
10514
|
|
|
@@ -9911,7 +10523,15 @@ namespace Rice4RubyQt6::detail
|
|
|
9911
10523
|
wrapper = new Wrapper_T(rb_data_type, data, true);
|
|
9912
10524
|
RTYPEDDATA_DATA(value) = wrapper;
|
|
9913
10525
|
|
|
9914
|
-
Registries::instance.instances.add(data, value);
|
|
10526
|
+
Registries::instance.instances.add(data, value, true);
|
|
10527
|
+
|
|
10528
|
+
// Copy keepAlive references from the source object (used by initialize_copy
|
|
10529
|
+
// so that cloned containers directly protect the same Ruby objects)
|
|
10530
|
+
if (source != Qnil)
|
|
10531
|
+
{
|
|
10532
|
+
WrapperBase* sourceWrapper = getWrapper(source);
|
|
10533
|
+
wrapper->setKeepAlive(sourceWrapper->getKeepAlive());
|
|
10534
|
+
}
|
|
9915
10535
|
|
|
9916
10536
|
return wrapper;
|
|
9917
10537
|
}
|
|
@@ -10233,7 +10853,7 @@ namespace Rice4RubyQt6::detail
|
|
|
10233
10853
|
std::map<std::string, VALUE> result;
|
|
10234
10854
|
|
|
10235
10855
|
// Keyword handling
|
|
10236
|
-
if (rb_keyword_given_p
|
|
10856
|
+
if (protect(rb_keyword_given_p))
|
|
10237
10857
|
{
|
|
10238
10858
|
// Keywords are stored in the last element in a hash
|
|
10239
10859
|
size_t actualArgc = argc - 1;
|
|
@@ -10264,6 +10884,13 @@ namespace Rice4RubyQt6::detail
|
|
|
10264
10884
|
}
|
|
10265
10885
|
}
|
|
10266
10886
|
|
|
10887
|
+
// If a block is given we assume it maps to the last argument
|
|
10888
|
+
if (protect(rb_block_given_p))
|
|
10889
|
+
{
|
|
10890
|
+
std::string key = "arg_" + std::to_string(result.size());
|
|
10891
|
+
result[key] = protect(rb_block_proc);
|
|
10892
|
+
}
|
|
10893
|
+
|
|
10267
10894
|
return result;
|
|
10268
10895
|
}
|
|
10269
10896
|
|
|
@@ -10307,10 +10934,6 @@ namespace Rice4RubyQt6::detail
|
|
|
10307
10934
|
{
|
|
10308
10935
|
result[i] = parameter->defaultValueRuby();
|
|
10309
10936
|
}
|
|
10310
|
-
else if (arg->isBlock() && rb_block_given_p())
|
|
10311
|
-
{
|
|
10312
|
-
result[i] = protect(rb_block_proc);
|
|
10313
|
-
}
|
|
10314
10937
|
else if (validate)
|
|
10315
10938
|
{
|
|
10316
10939
|
std::string message = "Missing argument. Name: " + arg->name + ". Index: " + std::to_string(i) + ".";
|
|
@@ -10529,13 +11152,13 @@ namespace Rice4RubyQt6::detail
|
|
|
10529
11152
|
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
10530
11153
|
if (isBuffer)
|
|
10531
11154
|
{
|
|
10532
|
-
|
|
10533
|
-
return
|
|
11155
|
+
TypeDetail<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Attr_T>>>> typeDetail;
|
|
11156
|
+
return typeDetail.rubyKlass();
|
|
10534
11157
|
}
|
|
10535
11158
|
else
|
|
10536
11159
|
{
|
|
10537
|
-
|
|
10538
|
-
return
|
|
11160
|
+
TypeDetail<Attr_T> typeDetail;
|
|
11161
|
+
return typeDetail.rubyKlass();
|
|
10539
11162
|
}
|
|
10540
11163
|
}
|
|
10541
11164
|
}
|
|
@@ -10646,8 +11269,8 @@ namespace Rice4RubyQt6::detail
|
|
|
10646
11269
|
template<typename Attribute_T>
|
|
10647
11270
|
inline VALUE NativeAttributeSet<Attribute_T>::returnKlass()
|
|
10648
11271
|
{
|
|
10649
|
-
|
|
10650
|
-
return
|
|
11272
|
+
TypeDetail<Attr_T> typeDetail;
|
|
11273
|
+
return typeDetail.rubyKlass();
|
|
10651
11274
|
}
|
|
10652
11275
|
}
|
|
10653
11276
|
|
|
@@ -10795,8 +11418,8 @@ namespace Rice4RubyQt6::detail
|
|
|
10795
11418
|
{
|
|
10796
11419
|
std::ostringstream result;
|
|
10797
11420
|
|
|
10798
|
-
detail::
|
|
10799
|
-
result <<
|
|
11421
|
+
detail::TypeDetail<Return_T> typeDetail;
|
|
11422
|
+
result << typeDetail.simplifiedName() << " ";
|
|
10800
11423
|
result << this->name();
|
|
10801
11424
|
|
|
10802
11425
|
result << "(";
|
|
@@ -10904,13 +11527,13 @@ namespace Rice4RubyQt6::detail
|
|
|
10904
11527
|
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
10905
11528
|
if (isBuffer)
|
|
10906
11529
|
{
|
|
10907
|
-
|
|
10908
|
-
return
|
|
11530
|
+
TypeDetail<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Return_T>>>> typeDetail;
|
|
11531
|
+
return typeDetail.rubyKlass();
|
|
10909
11532
|
}
|
|
10910
11533
|
else
|
|
10911
11534
|
{
|
|
10912
|
-
|
|
10913
|
-
return
|
|
11535
|
+
TypeDetail<Return_T> typeDetail;
|
|
11536
|
+
return typeDetail.rubyKlass();
|
|
10914
11537
|
}
|
|
10915
11538
|
}
|
|
10916
11539
|
}
|
|
@@ -11055,7 +11678,12 @@ namespace Rice4RubyQt6::detail
|
|
|
11055
11678
|
detail::To_Ruby<To_Ruby_T> toRuby;
|
|
11056
11679
|
for (; it != end; ++it)
|
|
11057
11680
|
{
|
|
11058
|
-
|
|
11681
|
+
// Use auto&& to accept both reference- and value-returning iterators.
|
|
11682
|
+
// - If *it is an lvalue (T&), auto&& deduces to T&, no copy made.
|
|
11683
|
+
// - If *it is a prvalue (T), auto&& deduces to T&&, value binds to the temporary for the scope of this loop iteration.
|
|
11684
|
+
// This also avoids MSVC C4239 when convert expects a non-const lvalue reference.
|
|
11685
|
+
auto&& value = *it;
|
|
11686
|
+
protect(rb_yield, toRuby.convert(value));
|
|
11059
11687
|
}
|
|
11060
11688
|
|
|
11061
11689
|
return self;
|
|
@@ -11081,13 +11709,13 @@ namespace Rice4RubyQt6::detail
|
|
|
11081
11709
|
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
11082
11710
|
if (isBuffer)
|
|
11083
11711
|
{
|
|
11084
|
-
|
|
11085
|
-
return
|
|
11712
|
+
TypeDetail<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Value_T>>>> typeDetail;
|
|
11713
|
+
return typeDetail.rubyKlass();
|
|
11086
11714
|
}
|
|
11087
11715
|
else
|
|
11088
11716
|
{
|
|
11089
|
-
|
|
11090
|
-
return
|
|
11717
|
+
TypeDetail<Value_T> typeDetail;
|
|
11718
|
+
return typeDetail.rubyKlass();
|
|
11091
11719
|
}
|
|
11092
11720
|
}
|
|
11093
11721
|
}
|
|
@@ -11241,13 +11869,13 @@ namespace Rice4RubyQt6::detail
|
|
|
11241
11869
|
{
|
|
11242
11870
|
std::ostringstream result;
|
|
11243
11871
|
|
|
11244
|
-
detail::
|
|
11245
|
-
result <<
|
|
11246
|
-
|
|
11872
|
+
detail::TypeDetail<Return_T> typeDetailReturn;
|
|
11873
|
+
result << typeDetailReturn.simplifiedName() << " ";
|
|
11874
|
+
|
|
11247
11875
|
if (!std::is_null_pointer_v<Receiver_T>)
|
|
11248
11876
|
{
|
|
11249
|
-
detail::
|
|
11250
|
-
result <<
|
|
11877
|
+
detail::TypeDetail<Receiver_T> typeDetailReceiver;
|
|
11878
|
+
result << typeDetailReceiver.simplifiedName() << "::";
|
|
11251
11879
|
}
|
|
11252
11880
|
|
|
11253
11881
|
result << this->name();
|
|
@@ -11443,13 +12071,13 @@ namespace Rice4RubyQt6::detail
|
|
|
11443
12071
|
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
11444
12072
|
if (isBuffer)
|
|
11445
12073
|
{
|
|
11446
|
-
|
|
11447
|
-
return
|
|
12074
|
+
TypeDetail<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Return_T>>>> typeDetail;
|
|
12075
|
+
return typeDetail.rubyKlass();
|
|
11448
12076
|
}
|
|
11449
12077
|
else
|
|
11450
12078
|
{
|
|
11451
|
-
|
|
11452
|
-
return
|
|
12079
|
+
TypeDetail<Return_T> typeDetail;
|
|
12080
|
+
return typeDetail.rubyKlass();
|
|
11453
12081
|
}
|
|
11454
12082
|
}
|
|
11455
12083
|
}
|
|
@@ -11637,13 +12265,13 @@ namespace Rice4RubyQt6::detail
|
|
|
11637
12265
|
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
11638
12266
|
if (isBuffer)
|
|
11639
12267
|
{
|
|
11640
|
-
|
|
11641
|
-
return
|
|
12268
|
+
TypeDetail<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Return_T>>>> typeDetail;
|
|
12269
|
+
return typeDetail.rubyKlass();
|
|
11642
12270
|
}
|
|
11643
12271
|
else
|
|
11644
12272
|
{
|
|
11645
|
-
|
|
11646
|
-
return
|
|
12273
|
+
TypeDetail<Return_T> typeDetail;
|
|
12274
|
+
return typeDetail.rubyKlass();
|
|
11647
12275
|
}
|
|
11648
12276
|
}
|
|
11649
12277
|
}
|
|
@@ -11658,6 +12286,11 @@ namespace Rice4RubyQt6::detail
|
|
|
11658
12286
|
template<typename Callback_T>
|
|
11659
12287
|
class NativeCallback;
|
|
11660
12288
|
|
|
12289
|
+
// NativeCallback instances are never freed because there is no way for us to know
|
|
12290
|
+
// when they can be freed. At the same time, the Pin prevents the Ruby proc from being
|
|
12291
|
+
// garbage collected, which is necessary because C code may call the callback
|
|
12292
|
+
// at any time. This supports passing blocks to C callbacks without requiring the Ruby
|
|
12293
|
+
// user to manually hold a reference to a proc.
|
|
11661
12294
|
template<typename Return_T, typename ...Parameter_Ts>
|
|
11662
12295
|
class NativeCallback<Return_T(*)(Parameter_Ts...)> : public Native
|
|
11663
12296
|
{
|
|
@@ -11666,8 +12299,6 @@ namespace Rice4RubyQt6::detail
|
|
|
11666
12299
|
using NativeCallback_T = NativeCallback<Callback_T>;
|
|
11667
12300
|
using Tuple_T = std::tuple<Parameter_Ts...>;
|
|
11668
12301
|
|
|
11669
|
-
static VALUE finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
|
|
11670
|
-
|
|
11671
12302
|
template<typename ...Arg_Ts>
|
|
11672
12303
|
static void define(Arg_Ts&& ...args);
|
|
11673
12304
|
|
|
@@ -11707,7 +12338,7 @@ namespace Rice4RubyQt6::detail
|
|
|
11707
12338
|
template<std::size_t... I>
|
|
11708
12339
|
Return_T callRuby(std::index_sequence<I...>& indices, Parameter_Ts...args);
|
|
11709
12340
|
|
|
11710
|
-
|
|
12341
|
+
Pin proc_;
|
|
11711
12342
|
From_Ruby<Return_T> fromRuby_;
|
|
11712
12343
|
|
|
11713
12344
|
#ifdef HAVE_LIBFFI
|
|
@@ -11880,18 +12511,10 @@ namespace Rice4RubyQt6::detail
|
|
|
11880
12511
|
{
|
|
11881
12512
|
/* Loop over each value returned from Ruby and convert it to the appropriate C++ type based
|
|
11882
12513
|
on the arguments (Parameter_Ts) required by the C++ function. Arg_T may have const/volatile while
|
|
11883
|
-
the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
|
|
11884
|
-
which we let the compiler convert to const values as needed. This works except for
|
|
11885
|
-
T** -> const T**, see comment in convertToNative method. */
|
|
11886
|
-
return std::forward_as_tuple(extractArg<Parameter_Ts>(args[I])...);
|
|
11887
|
-
}
|
|
11888
|
-
|
|
11889
|
-
template<typename Return_T, typename ...Parameter_Ts>
|
|
11890
|
-
VALUE NativeCallback<Return_T(*)(Parameter_Ts...)>::finalizerCallback(VALUE, VALUE callback_arg, int, const VALUE*, VALUE)
|
|
11891
|
-
{
|
|
11892
|
-
NativeCallback_T* nativeCallback = (NativeCallback_T*)callback_arg;
|
|
11893
|
-
delete nativeCallback;
|
|
11894
|
-
return Qnil;
|
|
12514
|
+
the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
|
|
12515
|
+
which we let the compiler convert to const values as needed. This works except for
|
|
12516
|
+
T** -> const T**, see comment in convertToNative method. */
|
|
12517
|
+
return std::forward_as_tuple(extractArg<Parameter_Ts>(args[I])...);
|
|
11895
12518
|
}
|
|
11896
12519
|
|
|
11897
12520
|
template<typename Return_T, typename...Parameter_Ts>
|
|
@@ -11911,10 +12534,6 @@ namespace Rice4RubyQt6::detail
|
|
|
11911
12534
|
Native("callback", copyReturnInfo(), copyParameters()),
|
|
11912
12535
|
proc_(proc), fromRuby_(returnInfo_.get())
|
|
11913
12536
|
{
|
|
11914
|
-
// Tie the lifetime of the NativeCallback C++ instance to the lifetime of the Ruby proc object
|
|
11915
|
-
VALUE finalizer = rb_proc_new(NativeCallback_T::finalizerCallback, (VALUE)this);
|
|
11916
|
-
rb_define_finalizer(proc, finalizer);
|
|
11917
|
-
|
|
11918
12537
|
#ifdef HAVE_LIBFFI
|
|
11919
12538
|
// First setup description of callback
|
|
11920
12539
|
if (cif_.bytes == 0)
|
|
@@ -11941,8 +12560,6 @@ namespace Rice4RubyQt6::detail
|
|
|
11941
12560
|
|
|
11942
12561
|
NativeCallback_T::callback_ = nullptr;
|
|
11943
12562
|
NativeCallback_T::native_ = nullptr;
|
|
11944
|
-
|
|
11945
|
-
this->proc_ = Qnil;
|
|
11946
12563
|
}
|
|
11947
12564
|
|
|
11948
12565
|
template<typename Return_T, typename ...Parameter_Ts>
|
|
@@ -11961,7 +12578,7 @@ namespace Rice4RubyQt6::detail
|
|
|
11961
12578
|
convertToRuby(args)... };
|
|
11962
12579
|
|
|
11963
12580
|
static Identifier id("call");
|
|
11964
|
-
VALUE result = detail::protect(rb_funcallv, this->proc_, id.id(), (int)sizeof...(Parameter_Ts), values.data());
|
|
12581
|
+
VALUE result = detail::protect(rb_funcallv, this->proc_.value(), id.id(), (int)sizeof...(Parameter_Ts), values.data());
|
|
11965
12582
|
if constexpr (!std::is_void_v<Return_T>)
|
|
11966
12583
|
{
|
|
11967
12584
|
return this->fromRuby_.convert(result);
|
|
@@ -11994,13 +12611,13 @@ namespace Rice4RubyQt6::detail
|
|
|
11994
12611
|
bool isBuffer = dynamic_cast<ReturnBuffer*>(this->returnInfo_.get()) ? true : false;
|
|
11995
12612
|
if (isBuffer)
|
|
11996
12613
|
{
|
|
11997
|
-
|
|
11998
|
-
return
|
|
12614
|
+
TypeDetail<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Return_T>>>> typeDetail;
|
|
12615
|
+
return typeDetail.rubyKlass();
|
|
11999
12616
|
}
|
|
12000
12617
|
else
|
|
12001
12618
|
{
|
|
12002
|
-
|
|
12003
|
-
return
|
|
12619
|
+
TypeDetail<Return_T> typeDetail;
|
|
12620
|
+
return typeDetail.rubyKlass();
|
|
12004
12621
|
}
|
|
12005
12622
|
}
|
|
12006
12623
|
}
|
|
@@ -12057,7 +12674,7 @@ namespace Rice4RubyQt6::detail
|
|
|
12057
12674
|
|
|
12058
12675
|
double is_convertible(VALUE value)
|
|
12059
12676
|
{
|
|
12060
|
-
if (protect(rb_obj_is_proc, value) == Qtrue
|
|
12677
|
+
if (protect(rb_obj_is_proc, value) == Qtrue)
|
|
12061
12678
|
{
|
|
12062
12679
|
return Convertible::Exact;
|
|
12063
12680
|
}
|
|
@@ -12144,31 +12761,45 @@ namespace Rice4RubyQt6
|
|
|
12144
12761
|
// ========= Object.ipp =========
|
|
12145
12762
|
namespace Rice4RubyQt6
|
|
12146
12763
|
{
|
|
12147
|
-
inline
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
inline const Object Undef(Qundef);
|
|
12764
|
+
inline Object::Object() : value_(Qnil)
|
|
12765
|
+
{
|
|
12766
|
+
}
|
|
12151
12767
|
|
|
12152
|
-
|
|
12153
|
-
// to clean up in case it is on the stack
|
|
12154
|
-
inline Object::~Object()
|
|
12768
|
+
inline Object::Object(VALUE value) : value_(value)
|
|
12155
12769
|
{
|
|
12156
|
-
this->value_ = Qnil;
|
|
12157
12770
|
}
|
|
12158
12771
|
|
|
12159
|
-
|
|
12160
|
-
inline Object::Object(Object&& other)
|
|
12772
|
+
inline VALUE Object::value() const
|
|
12161
12773
|
{
|
|
12162
|
-
this->value_
|
|
12163
|
-
other.value_ = Qnil;
|
|
12774
|
+
return this->value_.value();
|
|
12164
12775
|
}
|
|
12165
12776
|
|
|
12166
|
-
|
|
12167
|
-
inline Object& Object::operator=(Object&& other)
|
|
12777
|
+
inline Object::operator VALUE() const
|
|
12168
12778
|
{
|
|
12169
|
-
this->
|
|
12170
|
-
|
|
12171
|
-
|
|
12779
|
+
return this->value();
|
|
12780
|
+
}
|
|
12781
|
+
|
|
12782
|
+
inline VALUE Object::validated_value() const
|
|
12783
|
+
{
|
|
12784
|
+
VALUE result = this->value();
|
|
12785
|
+
|
|
12786
|
+
if (result == Qnil)
|
|
12787
|
+
{
|
|
12788
|
+
std::string message = "Rice Object does not wrap a Ruby object";
|
|
12789
|
+
throw std::runtime_error(message.c_str());
|
|
12790
|
+
}
|
|
12791
|
+
|
|
12792
|
+
return result;
|
|
12793
|
+
}
|
|
12794
|
+
|
|
12795
|
+
inline Object::operator bool() const
|
|
12796
|
+
{
|
|
12797
|
+
return RTEST(this->value());
|
|
12798
|
+
}
|
|
12799
|
+
|
|
12800
|
+
inline bool Object::is_nil() const
|
|
12801
|
+
{
|
|
12802
|
+
return NIL_P(this->value());
|
|
12172
12803
|
}
|
|
12173
12804
|
|
|
12174
12805
|
template<typename ...Parameter_Ts>
|
|
@@ -12182,7 +12813,7 @@ namespace Rice4RubyQt6
|
|
|
12182
12813
|
easy to duplicate by setting GC.stress to true and calling a constructor
|
|
12183
12814
|
that takes multiple values like a std::pair wrapper. */
|
|
12184
12815
|
std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(std::forward<Parameter_Ts>(args))... };
|
|
12185
|
-
return detail::protect(rb_funcallv,
|
|
12816
|
+
return detail::protect(rb_funcallv, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data());
|
|
12186
12817
|
}
|
|
12187
12818
|
|
|
12188
12819
|
template<typename ...Parameter_Ts>
|
|
@@ -12190,13 +12821,13 @@ namespace Rice4RubyQt6
|
|
|
12190
12821
|
{
|
|
12191
12822
|
/* IMPORTANT - See call() above */
|
|
12192
12823
|
std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(args)... };
|
|
12193
|
-
return detail::protect(rb_funcallv_kw,
|
|
12824
|
+
return detail::protect(rb_funcallv_kw, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
|
|
12194
12825
|
}
|
|
12195
12826
|
|
|
12196
12827
|
template<typename T>
|
|
12197
12828
|
inline void Object::iv_set(Identifier name, T const& value)
|
|
12198
12829
|
{
|
|
12199
|
-
detail::protect(rb_ivar_set, this->
|
|
12830
|
+
detail::protect(rb_ivar_set, this->validated_value(), name.id(), detail::To_Ruby<T>().convert(value));
|
|
12200
12831
|
}
|
|
12201
12832
|
|
|
12202
12833
|
inline int Object::compare(Object const& other) const
|
|
@@ -12207,87 +12838,99 @@ namespace Rice4RubyQt6
|
|
|
12207
12838
|
|
|
12208
12839
|
inline bool Object::is_equal(const Object& other) const
|
|
12209
12840
|
{
|
|
12210
|
-
|
|
12841
|
+
if (this->is_nil() || other.is_nil())
|
|
12842
|
+
{
|
|
12843
|
+
return this->is_nil() && other.is_nil();
|
|
12844
|
+
}
|
|
12845
|
+
|
|
12846
|
+
VALUE result = detail::protect(rb_equal, this->validated_value(), other.validated_value());
|
|
12211
12847
|
return RB_TEST(result);
|
|
12212
12848
|
}
|
|
12213
12849
|
|
|
12214
12850
|
inline bool Object::is_eql(const Object& other) const
|
|
12215
12851
|
{
|
|
12216
|
-
|
|
12852
|
+
if (this->is_nil() || other.is_nil())
|
|
12853
|
+
{
|
|
12854
|
+
return this->is_nil() && other.is_nil();
|
|
12855
|
+
}
|
|
12856
|
+
|
|
12857
|
+
VALUE result = detail::protect(rb_eql, this->validated_value(), other.validated_value());
|
|
12217
12858
|
return RB_TEST(result);
|
|
12218
12859
|
}
|
|
12219
12860
|
|
|
12220
12861
|
inline void Object::freeze()
|
|
12221
12862
|
{
|
|
12222
|
-
detail::protect(rb_obj_freeze,
|
|
12863
|
+
detail::protect(rb_obj_freeze, this->validated_value());
|
|
12223
12864
|
}
|
|
12224
12865
|
|
|
12225
12866
|
inline bool Object::is_frozen() const
|
|
12226
12867
|
{
|
|
12227
|
-
return RB_OBJ_FROZEN(
|
|
12868
|
+
return RB_OBJ_FROZEN(this->validated_value());
|
|
12228
12869
|
}
|
|
12229
12870
|
|
|
12230
12871
|
inline int Object::rb_type() const
|
|
12231
12872
|
{
|
|
12232
|
-
return ::rb_type(this->
|
|
12873
|
+
return ::rb_type(this->validated_value());
|
|
12233
12874
|
}
|
|
12234
12875
|
|
|
12235
12876
|
inline VALUE Object::object_id() const
|
|
12236
12877
|
{
|
|
12237
|
-
return detail::protect(rb_obj_id, this->
|
|
12878
|
+
return detail::protect(rb_obj_id, this->validated_value());
|
|
12238
12879
|
}
|
|
12239
12880
|
|
|
12240
12881
|
inline bool Object::is_a(Object klass) const
|
|
12241
12882
|
{
|
|
12242
|
-
VALUE result = detail::protect(rb_obj_is_kind_of, this->
|
|
12883
|
+
VALUE result = detail::protect(rb_obj_is_kind_of, this->validated_value(), klass.validated_value());
|
|
12243
12884
|
return RB_TEST(result);
|
|
12244
12885
|
}
|
|
12245
12886
|
|
|
12246
12887
|
inline void Object::extend(Module const& mod)
|
|
12247
12888
|
{
|
|
12248
|
-
detail::protect(rb_extend_object, this->
|
|
12889
|
+
detail::protect(rb_extend_object, this->validated_value(), mod.validated_value());
|
|
12249
12890
|
}
|
|
12250
12891
|
|
|
12251
12892
|
inline bool Object::respond_to(Identifier id) const
|
|
12252
12893
|
{
|
|
12253
|
-
return bool(rb_respond_to(this->
|
|
12894
|
+
return bool(rb_respond_to(this->validated_value(), id.id()));
|
|
12254
12895
|
}
|
|
12255
12896
|
|
|
12256
12897
|
inline bool Object::is_instance_of(Object klass) const
|
|
12257
12898
|
{
|
|
12258
|
-
VALUE result = detail::protect(rb_obj_is_instance_of, this->
|
|
12899
|
+
VALUE result = detail::protect(rb_obj_is_instance_of, this->validated_value(), klass.validated_value());
|
|
12259
12900
|
return RB_TEST(result);
|
|
12260
12901
|
}
|
|
12261
12902
|
|
|
12262
12903
|
inline Object Object::iv_get(Identifier name) const
|
|
12263
12904
|
{
|
|
12264
|
-
return detail::protect(rb_ivar_get, this->
|
|
12905
|
+
return detail::protect(rb_ivar_get, this->validated_value(), name.id());
|
|
12265
12906
|
}
|
|
12266
12907
|
|
|
12267
12908
|
inline Object Object::attr_get(Identifier name) const
|
|
12268
12909
|
{
|
|
12269
|
-
return detail::protect(rb_attr_get, this->
|
|
12910
|
+
return detail::protect(rb_attr_get, this->validated_value(), name.id());
|
|
12270
12911
|
}
|
|
12271
12912
|
|
|
12272
|
-
inline void Object::set_value(VALUE
|
|
12913
|
+
inline void Object::set_value(VALUE value)
|
|
12273
12914
|
{
|
|
12274
|
-
value_ =
|
|
12915
|
+
this->value_ = Pin(value);
|
|
12275
12916
|
}
|
|
12276
12917
|
|
|
12277
12918
|
inline Object Object::const_get(Identifier name) const
|
|
12278
12919
|
{
|
|
12279
|
-
return detail::protect(rb_const_get, this->
|
|
12920
|
+
return detail::protect(rb_const_get, this->validated_value(), name.id());
|
|
12280
12921
|
}
|
|
12281
12922
|
|
|
12282
12923
|
inline bool Object::const_defined(Identifier name) const
|
|
12283
12924
|
{
|
|
12284
|
-
size_t result = detail::protect(rb_const_defined, this->
|
|
12925
|
+
size_t result = detail::protect(rb_const_defined, this->validated_value(), name.id());
|
|
12285
12926
|
return bool(result);
|
|
12286
12927
|
}
|
|
12287
12928
|
|
|
12288
12929
|
inline Object Object::const_set(Identifier name, Object value)
|
|
12289
12930
|
{
|
|
12290
|
-
|
|
12931
|
+
// We will allow setting constants to Qnil, or the decimal value of 4. This happens
|
|
12932
|
+
// in C++ libraries with enums. Thus use value() instead of validated_value
|
|
12933
|
+
detail::protect(rb_const_set, this->validated_value(), name.id(), value.value());
|
|
12291
12934
|
return value;
|
|
12292
12935
|
}
|
|
12293
12936
|
|
|
@@ -12302,13 +12945,12 @@ namespace Rice4RubyQt6
|
|
|
12302
12945
|
|
|
12303
12946
|
inline void Object::remove_const(Identifier name)
|
|
12304
12947
|
{
|
|
12305
|
-
detail::protect(rb_mod_remove_const, this->
|
|
12948
|
+
detail::protect(rb_mod_remove_const, this->validated_value(), name.to_sym());
|
|
12306
12949
|
}
|
|
12307
12950
|
|
|
12308
12951
|
inline bool operator==(Object const& lhs, Object const& rhs)
|
|
12309
12952
|
{
|
|
12310
|
-
|
|
12311
|
-
return result == Qtrue ? true : false;
|
|
12953
|
+
return lhs.is_equal(rhs);
|
|
12312
12954
|
}
|
|
12313
12955
|
|
|
12314
12956
|
inline bool operator!=(Object const& lhs, Object const& rhs)
|
|
@@ -12319,13 +12961,13 @@ namespace Rice4RubyQt6
|
|
|
12319
12961
|
inline bool operator<(Object const& lhs, Object const& rhs)
|
|
12320
12962
|
{
|
|
12321
12963
|
Object result = lhs.call("<", rhs);
|
|
12322
|
-
return result
|
|
12964
|
+
return result;
|
|
12323
12965
|
}
|
|
12324
12966
|
|
|
12325
12967
|
inline bool operator>(Object const& lhs, Object const& rhs)
|
|
12326
12968
|
{
|
|
12327
12969
|
Object result = lhs.call(">", rhs);
|
|
12328
|
-
return result
|
|
12970
|
+
return result;
|
|
12329
12971
|
}
|
|
12330
12972
|
}
|
|
12331
12973
|
|
|
@@ -12415,73 +13057,36 @@ namespace Rice4RubyQt6::detail
|
|
|
12415
13057
|
};
|
|
12416
13058
|
}
|
|
12417
13059
|
|
|
12418
|
-
// ========= Builtin_Object.ipp =========
|
|
12419
|
-
#include <algorithm>
|
|
12420
|
-
|
|
12421
|
-
namespace Rice4RubyQt6
|
|
12422
|
-
{
|
|
12423
|
-
namespace detail
|
|
12424
|
-
{
|
|
12425
|
-
inline VALUE check_type(Object value, int type)
|
|
12426
|
-
{
|
|
12427
|
-
detail::protect(rb_check_type, value.value(), type);
|
|
12428
|
-
return Qnil;
|
|
12429
|
-
}
|
|
12430
|
-
}
|
|
12431
|
-
|
|
12432
|
-
template<int Builtin_Type>
|
|
12433
|
-
inline Builtin_Object<Builtin_Type>::Builtin_Object(Object value) : Object(value)
|
|
12434
|
-
{
|
|
12435
|
-
detail::check_type(value, Builtin_Type);
|
|
12436
|
-
}
|
|
12437
|
-
|
|
12438
|
-
template<int Builtin_Type>
|
|
12439
|
-
inline RObject& Builtin_Object<Builtin_Type>::operator*() const
|
|
12440
|
-
{
|
|
12441
|
-
return *ROBJECT(this->value());
|
|
12442
|
-
}
|
|
12443
|
-
|
|
12444
|
-
template<int Builtin_Type>
|
|
12445
|
-
inline RObject* Builtin_Object<Builtin_Type>::operator->() const
|
|
12446
|
-
{
|
|
12447
|
-
return ROBJECT(this->value());
|
|
12448
|
-
}
|
|
12449
|
-
|
|
12450
|
-
template<int Builtin_Type>
|
|
12451
|
-
inline RObject* Builtin_Object<Builtin_Type>::get() const
|
|
12452
|
-
{
|
|
12453
|
-
return ROBJECT(this->value());
|
|
12454
|
-
}
|
|
12455
|
-
} // namespace Rice4RubyQt6
|
|
12456
|
-
|
|
12457
13060
|
// ========= String.ipp =========
|
|
12458
13061
|
namespace Rice4RubyQt6
|
|
12459
13062
|
{
|
|
12460
|
-
inline String::String() :
|
|
13063
|
+
inline String::String() : Object(detail::protect(rb_str_new2, ""))
|
|
12461
13064
|
{
|
|
12462
13065
|
}
|
|
12463
13066
|
|
|
12464
|
-
inline String::String(VALUE v) :
|
|
13067
|
+
inline String::String(VALUE v) : Object(v)
|
|
12465
13068
|
{
|
|
13069
|
+
detail::protect(rb_check_type, this->value(), T_STRING);
|
|
12466
13070
|
}
|
|
12467
13071
|
|
|
12468
|
-
inline String::String(Object v) :
|
|
13072
|
+
inline String::String(Object v) : Object(v)
|
|
12469
13073
|
{
|
|
13074
|
+
detail::protect(rb_check_type, this->value(), T_STRING);
|
|
12470
13075
|
}
|
|
12471
13076
|
|
|
12472
|
-
inline String::String(char const* s) :
|
|
13077
|
+
inline String::String(char const* s) : Object(detail::protect(rb_utf8_str_new_cstr, s))
|
|
12473
13078
|
{
|
|
12474
13079
|
}
|
|
12475
13080
|
|
|
12476
|
-
inline String::String(std::string const& s) :
|
|
13081
|
+
inline String::String(std::string const& s) : Object(detail::protect(rb_utf8_str_new, s.data(), (long)s.length()))
|
|
12477
13082
|
{
|
|
12478
13083
|
}
|
|
12479
13084
|
|
|
12480
|
-
inline String::String(std::string_view const& s) :
|
|
13085
|
+
inline String::String(std::string_view const& s) : Object(detail::protect(rb_utf8_str_new, s.data(), (long)s.length()))
|
|
12481
13086
|
{
|
|
12482
13087
|
}
|
|
12483
13088
|
|
|
12484
|
-
inline String::String(Identifier id) :
|
|
13089
|
+
inline String::String(Identifier id) : Object(detail::protect(rb_utf8_str_new_cstr, id.c_str()))
|
|
12485
13090
|
{
|
|
12486
13091
|
}
|
|
12487
13092
|
|
|
@@ -12502,22 +13107,22 @@ namespace Rice4RubyQt6
|
|
|
12502
13107
|
|
|
12503
13108
|
inline size_t String::length() const
|
|
12504
13109
|
{
|
|
12505
|
-
return RSTRING_LEN(value());
|
|
13110
|
+
return RSTRING_LEN(this->value());
|
|
12506
13111
|
}
|
|
12507
13112
|
|
|
12508
13113
|
inline char String::operator[](ptrdiff_t index) const
|
|
12509
13114
|
{
|
|
12510
|
-
return RSTRING_PTR(value())[index];
|
|
13115
|
+
return RSTRING_PTR(this->value())[index];
|
|
12511
13116
|
}
|
|
12512
13117
|
|
|
12513
13118
|
inline char const* String::c_str() const
|
|
12514
13119
|
{
|
|
12515
|
-
return RSTRING_PTR(value());
|
|
13120
|
+
return RSTRING_PTR(this->value());
|
|
12516
13121
|
}
|
|
12517
13122
|
|
|
12518
13123
|
inline std::string String::str() const
|
|
12519
13124
|
{
|
|
12520
|
-
return std::string(RSTRING_PTR(value()), length());
|
|
13125
|
+
return std::string(RSTRING_PTR(this->value()), length());
|
|
12521
13126
|
}
|
|
12522
13127
|
|
|
12523
13128
|
template<typename T>
|
|
@@ -12598,28 +13203,31 @@ namespace Rice4RubyQt6::detail
|
|
|
12598
13203
|
Arg* arg_ = nullptr;
|
|
12599
13204
|
};
|
|
12600
13205
|
}
|
|
13206
|
+
|
|
12601
13207
|
// ========= Array.ipp =========
|
|
12602
13208
|
|
|
12603
13209
|
namespace Rice4RubyQt6
|
|
12604
13210
|
{
|
|
12605
|
-
inline Array::Array() :
|
|
13211
|
+
inline Array::Array() : Object(detail::protect(rb_ary_new))
|
|
12606
13212
|
{
|
|
12607
13213
|
}
|
|
12608
13214
|
|
|
12609
|
-
inline Array::Array(long capacity) :
|
|
13215
|
+
inline Array::Array(long capacity) : Object(detail::protect(rb_ary_new_capa, capacity))
|
|
12610
13216
|
{
|
|
12611
13217
|
}
|
|
12612
13218
|
|
|
12613
|
-
inline Array::Array(Object v) :
|
|
13219
|
+
inline Array::Array(Object v) : Object(v)
|
|
12614
13220
|
{
|
|
13221
|
+
detail::protect(rb_check_type, this->value(), T_ARRAY);
|
|
12615
13222
|
}
|
|
12616
13223
|
|
|
12617
|
-
inline Array::Array(VALUE v) :
|
|
13224
|
+
inline Array::Array(VALUE v) : Object(v)
|
|
12618
13225
|
{
|
|
13226
|
+
detail::protect(rb_check_type, this->value(), T_ARRAY);
|
|
12619
13227
|
}
|
|
12620
13228
|
|
|
12621
13229
|
template<typename Iter_T>
|
|
12622
|
-
inline Array::Array(Iter_T it, Iter_T end) :
|
|
13230
|
+
inline Array::Array(Iter_T it, Iter_T end) : Object(detail::protect(rb_ary_new))
|
|
12623
13231
|
{
|
|
12624
13232
|
for (; it != end; ++it)
|
|
12625
13233
|
{
|
|
@@ -12628,7 +13236,7 @@ namespace Rice4RubyQt6
|
|
|
12628
13236
|
}
|
|
12629
13237
|
|
|
12630
13238
|
template<typename T, long n>
|
|
12631
|
-
inline Array::Array(T (&a)[n]) :
|
|
13239
|
+
inline Array::Array(T (&a)[n]) : Object(detail::protect(rb_ary_new))
|
|
12632
13240
|
{
|
|
12633
13241
|
for (long j = 0; j < n; ++j)
|
|
12634
13242
|
{
|
|
@@ -12733,9 +13341,9 @@ namespace Rice4RubyQt6
|
|
|
12733
13341
|
return detail::protect(rb_ary_entry, array_.value(), index_);
|
|
12734
13342
|
}
|
|
12735
13343
|
|
|
12736
|
-
inline Array::Proxy::operator
|
|
13344
|
+
inline Array::Proxy::operator VALUE() const
|
|
12737
13345
|
{
|
|
12738
|
-
return
|
|
13346
|
+
return this->value();
|
|
12739
13347
|
}
|
|
12740
13348
|
|
|
12741
13349
|
template<typename T>
|
|
@@ -12793,7 +13401,7 @@ namespace Rice4RubyQt6
|
|
|
12793
13401
|
template<typename Array_Ptr_T, typename Value_T>
|
|
12794
13402
|
inline Object* Array::Iterator<Array_Ptr_T, Value_T>::operator->()
|
|
12795
13403
|
{
|
|
12796
|
-
tmp_ = (*array_)[index_];
|
|
13404
|
+
tmp_ = Object((*array_)[index_]);
|
|
12797
13405
|
return &tmp_;
|
|
12798
13406
|
}
|
|
12799
13407
|
|
|
@@ -13047,12 +13655,13 @@ namespace Rice4RubyQt6::detail
|
|
|
13047
13655
|
|
|
13048
13656
|
namespace Rice4RubyQt6
|
|
13049
13657
|
{
|
|
13050
|
-
inline Hash::Hash() :
|
|
13658
|
+
inline Hash::Hash() : Object(detail::protect(rb_hash_new))
|
|
13051
13659
|
{
|
|
13052
13660
|
}
|
|
13053
13661
|
|
|
13054
|
-
inline Hash::Hash(Object v) :
|
|
13662
|
+
inline Hash::Hash(Object v) : Object(v)
|
|
13055
13663
|
{
|
|
13664
|
+
detail::protect(rb_check_type, this->value(), T_HASH);
|
|
13056
13665
|
}
|
|
13057
13666
|
|
|
13058
13667
|
inline size_t Hash::size() const
|
|
@@ -13064,7 +13673,7 @@ namespace Rice4RubyQt6
|
|
|
13064
13673
|
{
|
|
13065
13674
|
}
|
|
13066
13675
|
|
|
13067
|
-
inline Hash::Proxy::operator
|
|
13676
|
+
inline Hash::Proxy::operator VALUE() const
|
|
13068
13677
|
{
|
|
13069
13678
|
return value();
|
|
13070
13679
|
}
|
|
@@ -13096,7 +13705,7 @@ namespace Rice4RubyQt6
|
|
|
13096
13705
|
inline Value_T Hash::get(Key_T const& key)
|
|
13097
13706
|
{
|
|
13098
13707
|
Object ruby_key(detail::To_Ruby<Key_T>().convert(key));
|
|
13099
|
-
Object value
|
|
13708
|
+
Object value(operator[](ruby_key));
|
|
13100
13709
|
try
|
|
13101
13710
|
{
|
|
13102
13711
|
return detail::From_Ruby<Value_T>().convert(value);
|
|
@@ -13200,7 +13809,7 @@ namespace Rice4RubyQt6
|
|
|
13200
13809
|
template<typename Hash_Ptr_T, typename Value_T>
|
|
13201
13810
|
inline Object Hash::Iterator<Hash_Ptr_T, Value_T>::current_key()
|
|
13202
13811
|
{
|
|
13203
|
-
return hash_keys()[current_index_];
|
|
13812
|
+
return Object(hash_keys()[current_index_]);
|
|
13204
13813
|
}
|
|
13205
13814
|
|
|
13206
13815
|
template<typename Hash_Ptr_T, typename Value_T>
|
|
@@ -13467,10 +14076,6 @@ namespace Rice4RubyQt6::detail
|
|
|
13467
14076
|
|
|
13468
14077
|
namespace Rice4RubyQt6
|
|
13469
14078
|
{
|
|
13470
|
-
inline Module::Module() : Object(rb_cObject)
|
|
13471
|
-
{
|
|
13472
|
-
}
|
|
13473
|
-
|
|
13474
14079
|
inline Module::Module(VALUE value) : Object(value)
|
|
13475
14080
|
{
|
|
13476
14081
|
if (::rb_type(value) != T_CLASS && ::rb_type(value) != T_MODULE)
|
|
@@ -13482,7 +14087,7 @@ namespace Rice4RubyQt6
|
|
|
13482
14087
|
}
|
|
13483
14088
|
}
|
|
13484
14089
|
|
|
13485
|
-
//! Construct a Module from
|
|
14090
|
+
//! Construct a Module from a string that references a Module
|
|
13486
14091
|
inline Module::Module(std::string name, Object under)
|
|
13487
14092
|
{
|
|
13488
14093
|
VALUE result = under.const_get(name);
|
|
@@ -13808,7 +14413,7 @@ namespace Rice4RubyQt6
|
|
|
13808
14413
|
|
|
13809
14414
|
//! An instance of a Struct
|
|
13810
14415
|
//! \sa Struct
|
|
13811
|
-
class Struct::Instance : public
|
|
14416
|
+
class Struct::Instance : public Object
|
|
13812
14417
|
{
|
|
13813
14418
|
public:
|
|
13814
14419
|
//! Create a new Instance of a Struct.
|
|
@@ -13859,7 +14464,7 @@ namespace Rice4RubyQt6
|
|
|
13859
14464
|
|
|
13860
14465
|
inline Struct& Struct::define_member(Identifier name)
|
|
13861
14466
|
{
|
|
13862
|
-
if (
|
|
14467
|
+
if (!this->is_nil())
|
|
13863
14468
|
{
|
|
13864
14469
|
throw std::runtime_error("struct is already initialized");
|
|
13865
14470
|
}
|
|
@@ -13871,7 +14476,7 @@ namespace Rice4RubyQt6
|
|
|
13871
14476
|
|
|
13872
14477
|
inline Array Struct::members() const
|
|
13873
14478
|
{
|
|
13874
|
-
if (
|
|
14479
|
+
if (this->is_nil())
|
|
13875
14480
|
{
|
|
13876
14481
|
// Struct is not yet defined
|
|
13877
14482
|
return Array(members_.begin(), members_.end());
|
|
@@ -13890,13 +14495,15 @@ namespace Rice4RubyQt6
|
|
|
13890
14495
|
}
|
|
13891
14496
|
|
|
13892
14497
|
inline Struct::Instance::Instance(Struct const& type, Array args) :
|
|
13893
|
-
|
|
14498
|
+
Object(type.new_instance(args)), type_(type)
|
|
13894
14499
|
{
|
|
14500
|
+
detail::protect(rb_check_type, this->value(), T_STRUCT);
|
|
13895
14501
|
}
|
|
13896
14502
|
|
|
13897
14503
|
inline Struct::Instance::Instance(Struct const& type, Object s) :
|
|
13898
|
-
|
|
14504
|
+
Object(s), type_(type)
|
|
13899
14505
|
{
|
|
14506
|
+
detail::protect(rb_check_type, this->value(), T_STRUCT);
|
|
13900
14507
|
}
|
|
13901
14508
|
|
|
13902
14509
|
inline Struct define_struct()
|
|
@@ -13940,162 +14547,6 @@ namespace Rice4RubyQt6::detail
|
|
|
13940
14547
|
};
|
|
13941
14548
|
}
|
|
13942
14549
|
|
|
13943
|
-
// ========= Address_Registration_Guard.hpp =========
|
|
13944
|
-
|
|
13945
|
-
namespace Rice4RubyQt6
|
|
13946
|
-
{
|
|
13947
|
-
//! A guard to register a given address with the GC.
|
|
13948
|
-
/*! Calls rb_gc_register_address upon construction and
|
|
13949
|
-
* rb_gc_unregister_address upon destruction.
|
|
13950
|
-
* For example:
|
|
13951
|
-
* \code
|
|
13952
|
-
* Class Foo
|
|
13953
|
-
* {
|
|
13954
|
-
* public:
|
|
13955
|
-
* Foo()
|
|
13956
|
-
* : string_(rb_str_new2())
|
|
13957
|
-
* , guard_(&string_);
|
|
13958
|
-
*
|
|
13959
|
-
* private:
|
|
13960
|
-
* VALUE string_;
|
|
13961
|
-
* Address_Registration_Guard guard_;
|
|
13962
|
-
* };
|
|
13963
|
-
* \endcode
|
|
13964
|
-
*/
|
|
13965
|
-
class Address_Registration_Guard
|
|
13966
|
-
{
|
|
13967
|
-
public:
|
|
13968
|
-
//! Register an address with the GC.
|
|
13969
|
-
/* \param address The address to register with the GC. The address
|
|
13970
|
-
* must point to a valid ruby object (RObject).
|
|
13971
|
-
*/
|
|
13972
|
-
Address_Registration_Guard(VALUE* address);
|
|
13973
|
-
|
|
13974
|
-
//! Register an Object with the GC.
|
|
13975
|
-
/*! \param object The Object to register with the GC. The object must
|
|
13976
|
-
* not be destroyed before the Address_Registration_Guard is
|
|
13977
|
-
* destroyed.
|
|
13978
|
-
*/
|
|
13979
|
-
Address_Registration_Guard(Object* object);
|
|
13980
|
-
|
|
13981
|
-
//! Unregister an address/Object with the GC.
|
|
13982
|
-
/*! Destruct an Address_Registration_Guard. The address registered
|
|
13983
|
-
* with the Address_Registration_Guard when it was constructed will
|
|
13984
|
-
* be unregistered from the GC.
|
|
13985
|
-
*/
|
|
13986
|
-
~Address_Registration_Guard();
|
|
13987
|
-
|
|
13988
|
-
// Disable copying
|
|
13989
|
-
Address_Registration_Guard(Address_Registration_Guard const& other) = delete;
|
|
13990
|
-
Address_Registration_Guard& operator=(Address_Registration_Guard const& other) = delete;
|
|
13991
|
-
|
|
13992
|
-
// Enable moving
|
|
13993
|
-
Address_Registration_Guard(Address_Registration_Guard&& other);
|
|
13994
|
-
Address_Registration_Guard& operator=(Address_Registration_Guard&& other);
|
|
13995
|
-
|
|
13996
|
-
//! Get the address that is registered with the GC.
|
|
13997
|
-
VALUE* address() const;
|
|
13998
|
-
|
|
13999
|
-
/** Called during Ruby's exit process since we should not call
|
|
14000
|
-
* rb_gc unregister_address there
|
|
14001
|
-
*/
|
|
14002
|
-
static void disable();
|
|
14003
|
-
|
|
14004
|
-
private:
|
|
14005
|
-
inline static bool enabled = true;
|
|
14006
|
-
inline static bool exit_handler_registered = false;
|
|
14007
|
-
static void registerExitHandler();
|
|
14008
|
-
|
|
14009
|
-
private:
|
|
14010
|
-
void registerAddress() const;
|
|
14011
|
-
void unregisterAddress();
|
|
14012
|
-
|
|
14013
|
-
VALUE* address_ = nullptr;
|
|
14014
|
-
};
|
|
14015
|
-
} // namespace Rice4RubyQt6
|
|
14016
|
-
|
|
14017
|
-
|
|
14018
|
-
// ========= Address_Registration_Guard.ipp =========
|
|
14019
|
-
namespace Rice4RubyQt6
|
|
14020
|
-
{
|
|
14021
|
-
inline Address_Registration_Guard::Address_Registration_Guard(VALUE* address) : address_(address)
|
|
14022
|
-
{
|
|
14023
|
-
registerExitHandler();
|
|
14024
|
-
registerAddress();
|
|
14025
|
-
}
|
|
14026
|
-
|
|
14027
|
-
inline Address_Registration_Guard::Address_Registration_Guard(Object* object)
|
|
14028
|
-
: address_(const_cast<VALUE*>(&object->value()))
|
|
14029
|
-
{
|
|
14030
|
-
registerExitHandler();
|
|
14031
|
-
registerAddress();
|
|
14032
|
-
}
|
|
14033
|
-
|
|
14034
|
-
inline Address_Registration_Guard::~Address_Registration_Guard()
|
|
14035
|
-
{
|
|
14036
|
-
unregisterAddress();
|
|
14037
|
-
}
|
|
14038
|
-
|
|
14039
|
-
inline Address_Registration_Guard::Address_Registration_Guard(Address_Registration_Guard&& other)
|
|
14040
|
-
{
|
|
14041
|
-
// We don't use the constructor because we don't want to double register this address
|
|
14042
|
-
address_ = other.address_;
|
|
14043
|
-
other.address_ = nullptr;
|
|
14044
|
-
}
|
|
14045
|
-
|
|
14046
|
-
inline Address_Registration_Guard& Address_Registration_Guard::operator=(Address_Registration_Guard&& other)
|
|
14047
|
-
{
|
|
14048
|
-
this->unregisterAddress();
|
|
14049
|
-
|
|
14050
|
-
this->address_ = other.address_;
|
|
14051
|
-
other.address_ = nullptr;
|
|
14052
|
-
return *this;
|
|
14053
|
-
}
|
|
14054
|
-
|
|
14055
|
-
inline void Address_Registration_Guard::registerAddress() const
|
|
14056
|
-
{
|
|
14057
|
-
if (enabled)
|
|
14058
|
-
{
|
|
14059
|
-
detail::protect(rb_gc_register_address, address_);
|
|
14060
|
-
}
|
|
14061
|
-
}
|
|
14062
|
-
|
|
14063
|
-
inline void Address_Registration_Guard::unregisterAddress()
|
|
14064
|
-
{
|
|
14065
|
-
if (enabled && address_)
|
|
14066
|
-
{
|
|
14067
|
-
detail::protect(rb_gc_unregister_address, address_);
|
|
14068
|
-
}
|
|
14069
|
-
|
|
14070
|
-
address_ = nullptr;
|
|
14071
|
-
}
|
|
14072
|
-
|
|
14073
|
-
inline VALUE* Address_Registration_Guard::address() const
|
|
14074
|
-
{
|
|
14075
|
-
return address_;
|
|
14076
|
-
}
|
|
14077
|
-
|
|
14078
|
-
static void disable_all_guards(VALUE)
|
|
14079
|
-
{
|
|
14080
|
-
Address_Registration_Guard::disable();
|
|
14081
|
-
}
|
|
14082
|
-
|
|
14083
|
-
inline void Address_Registration_Guard::registerExitHandler()
|
|
14084
|
-
{
|
|
14085
|
-
if (exit_handler_registered)
|
|
14086
|
-
{
|
|
14087
|
-
return;
|
|
14088
|
-
}
|
|
14089
|
-
|
|
14090
|
-
detail::protect(rb_set_end_proc, &disable_all_guards, Qnil);
|
|
14091
|
-
exit_handler_registered = true;
|
|
14092
|
-
}
|
|
14093
|
-
|
|
14094
|
-
inline void Address_Registration_Guard::disable()
|
|
14095
|
-
{
|
|
14096
|
-
enabled = false;
|
|
14097
|
-
}
|
|
14098
|
-
} // Rice
|
|
14099
14550
|
// ========= global_function.hpp =========
|
|
14100
14551
|
|
|
14101
14552
|
namespace Rice4RubyQt6
|
|
@@ -14166,9 +14617,7 @@ namespace Rice4RubyQt6
|
|
|
14166
14617
|
public:
|
|
14167
14618
|
//! Construct new Director. Needs the Ruby object so that the
|
|
14168
14619
|
// proxy class can call methods on that object.
|
|
14169
|
-
Director(Object self)
|
|
14170
|
-
{
|
|
14171
|
-
}
|
|
14620
|
+
Director(Object self);
|
|
14172
14621
|
|
|
14173
14622
|
virtual ~Director() = default;
|
|
14174
14623
|
|
|
@@ -14177,13 +14626,10 @@ namespace Rice4RubyQt6
|
|
|
14177
14626
|
* method, use this method to throw an exception in this case.
|
|
14178
14627
|
*/
|
|
14179
14628
|
[[noreturn]]
|
|
14180
|
-
void raisePureVirtual() const
|
|
14181
|
-
{
|
|
14182
|
-
rb_raise(rb_eNotImpError, "Cannot call super() into a pure-virtual C++ method");
|
|
14183
|
-
}
|
|
14629
|
+
void raisePureVirtual() const;
|
|
14184
14630
|
|
|
14185
14631
|
//! Get the Ruby object linked to this C++ instance
|
|
14186
|
-
Object getSelf() const
|
|
14632
|
+
Object getSelf() const;
|
|
14187
14633
|
|
|
14188
14634
|
private:
|
|
14189
14635
|
|
|
@@ -14193,6 +14639,25 @@ namespace Rice4RubyQt6
|
|
|
14193
14639
|
};
|
|
14194
14640
|
}
|
|
14195
14641
|
|
|
14642
|
+
// ========= Director.ipp =========
|
|
14643
|
+
|
|
14644
|
+
namespace Rice4RubyQt6
|
|
14645
|
+
{
|
|
14646
|
+
inline Director::Director(Object self) : self_(self)
|
|
14647
|
+
{
|
|
14648
|
+
}
|
|
14649
|
+
|
|
14650
|
+
inline void Director::raisePureVirtual() const
|
|
14651
|
+
{
|
|
14652
|
+
rb_raise(rb_eNotImpError, "Cannot call super() into a pure-virtual C++ method");
|
|
14653
|
+
}
|
|
14654
|
+
|
|
14655
|
+
inline Object Director::getSelf() const
|
|
14656
|
+
{
|
|
14657
|
+
return self_;
|
|
14658
|
+
}
|
|
14659
|
+
}
|
|
14660
|
+
|
|
14196
14661
|
// ========= Data_Type.ipp =========
|
|
14197
14662
|
#include <stdexcept>
|
|
14198
14663
|
|
|
@@ -14201,16 +14666,13 @@ namespace Rice4RubyQt6
|
|
|
14201
14666
|
template<typename T>
|
|
14202
14667
|
inline void ruby_mark_internal(detail::WrapperBase* wrapper)
|
|
14203
14668
|
{
|
|
14204
|
-
|
|
14205
|
-
|
|
14206
|
-
// Tell the wrapper to mark the objects its keeping alive
|
|
14207
|
-
wrapper->ruby_mark();
|
|
14669
|
+
// Tell the wrapper to mark the objects its keeping alive
|
|
14670
|
+
wrapper->ruby_mark();
|
|
14208
14671
|
|
|
14209
|
-
|
|
14210
|
-
|
|
14211
|
-
|
|
14212
|
-
|
|
14213
|
-
});
|
|
14672
|
+
// Get the underlying data and call custom mark function (if any)
|
|
14673
|
+
// Use the wrapper's stored rb_data_type to avoid type mismatch
|
|
14674
|
+
T* data = static_cast<T*>(wrapper->get(Data_Type<T>::ruby_data_type()));
|
|
14675
|
+
ruby_mark<T>(data);
|
|
14214
14676
|
}
|
|
14215
14677
|
|
|
14216
14678
|
template<typename T>
|
|
@@ -14223,7 +14685,14 @@ namespace Rice4RubyQt6
|
|
|
14223
14685
|
template<typename T>
|
|
14224
14686
|
inline size_t ruby_size_internal(const T*)
|
|
14225
14687
|
{
|
|
14226
|
-
|
|
14688
|
+
if constexpr (detail::is_complete_v<T>)
|
|
14689
|
+
{
|
|
14690
|
+
return sizeof(T);
|
|
14691
|
+
}
|
|
14692
|
+
else
|
|
14693
|
+
{
|
|
14694
|
+
return 0;
|
|
14695
|
+
}
|
|
14227
14696
|
}
|
|
14228
14697
|
|
|
14229
14698
|
template<>
|
|
@@ -14234,17 +14703,19 @@ namespace Rice4RubyQt6
|
|
|
14234
14703
|
|
|
14235
14704
|
template<typename T>
|
|
14236
14705
|
template <typename Base_T>
|
|
14237
|
-
inline Data_Type<T> Data_Type<T>::bind(const Module& klass)
|
|
14706
|
+
inline Data_Type<T> Data_Type<T>::bind(const Module& klass, rb_data_type_t *data_type)
|
|
14238
14707
|
{
|
|
14239
14708
|
if (is_bound())
|
|
14240
14709
|
{
|
|
14241
|
-
|
|
14242
|
-
std::string message = "Type " + typeIndexParser.name() + " is already bound to a different type";
|
|
14710
|
+
std::string message = "Type " + detail::TypeDetail<T>().name() + " is already bound to a different type";
|
|
14243
14711
|
throw std::runtime_error(message.c_str());
|
|
14244
14712
|
}
|
|
14245
14713
|
|
|
14246
14714
|
klass_ = klass;
|
|
14247
14715
|
|
|
14716
|
+
if (data_type) {
|
|
14717
|
+
rb_data_type_ = data_type;
|
|
14718
|
+
} else {
|
|
14248
14719
|
rb_data_type_ = new rb_data_type_t();
|
|
14249
14720
|
rb_data_type_->wrap_struct_name = strdup(Rice4RubyQt6::detail::protect(rb_class2name, klass_));
|
|
14250
14721
|
rb_data_type_->function.dmark = reinterpret_cast<void(*)(void*)>(&Rice4RubyQt6::ruby_mark_internal<T>);
|
|
@@ -14257,6 +14728,7 @@ namespace Rice4RubyQt6
|
|
|
14257
14728
|
{
|
|
14258
14729
|
rb_data_type_->parent = Data_Type<Base_T>::ruby_data_type();
|
|
14259
14730
|
}
|
|
14731
|
+
}
|
|
14260
14732
|
|
|
14261
14733
|
auto instances = unbound_instances();
|
|
14262
14734
|
for (auto instance: instances)
|
|
@@ -14270,15 +14742,32 @@ namespace Rice4RubyQt6
|
|
|
14270
14742
|
|
|
14271
14743
|
// Add a method to get the source C++ class name from Ruby
|
|
14272
14744
|
Data_Type<T> dataType;
|
|
14273
|
-
|
|
14745
|
+
if constexpr (detail::is_complete_v<T>)
|
|
14274
14746
|
{
|
|
14275
|
-
|
|
14276
|
-
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
|
|
14280
|
-
|
|
14747
|
+
dataType.define_singleton_method("cpp_class", [](VALUE) -> VALUE
|
|
14748
|
+
{
|
|
14749
|
+
Return returnInfo;
|
|
14750
|
+
returnInfo.takeOwnership();
|
|
14751
|
+
|
|
14752
|
+
detail::TypeDetail<T> typeDetail;
|
|
14753
|
+
std::string cppClassName = typeDetail.simplifiedName();
|
|
14754
|
+
|
|
14755
|
+
return detail::To_Ruby<char*>(&returnInfo).convert(cppClassName.c_str());
|
|
14756
|
+
}, Arg("klass").setValue(), Return().setValue());
|
|
14757
|
+
}
|
|
14758
|
+
else
|
|
14759
|
+
{
|
|
14760
|
+
VALUE klass_value = klass.value();
|
|
14761
|
+
dataType.define_singleton_method("cpp_class", [klass_value](VALUE) -> VALUE
|
|
14762
|
+
{
|
|
14763
|
+
Return returnInfo;
|
|
14764
|
+
returnInfo.takeOwnership();
|
|
14281
14765
|
|
|
14766
|
+
Rice4RubyQt6::String cppClassName = detail::protect(rb_class_path, klass_value);
|
|
14767
|
+
|
|
14768
|
+
return detail::To_Ruby<char*>(&returnInfo).convert(cppClassName.c_str());
|
|
14769
|
+
}, Arg("klass").setValue(), Return().setValue());
|
|
14770
|
+
}
|
|
14282
14771
|
return dataType;
|
|
14283
14772
|
}
|
|
14284
14773
|
|
|
@@ -14368,8 +14857,23 @@ namespace Rice4RubyQt6
|
|
|
14368
14857
|
|
|
14369
14858
|
if constexpr (Constructor_T::isCopyConstructor())
|
|
14370
14859
|
{
|
|
14371
|
-
// Define initialize_copy that will copy the C++ object
|
|
14372
|
-
|
|
14860
|
+
// Define initialize_copy that will copy the C++ object and its keepAlive references.
|
|
14861
|
+
// We use setValue() so Rice passes the raw VALUE without conversion - this gives
|
|
14862
|
+
// initialize_copy access to both wrappers so it can copy the keepAlive list.
|
|
14863
|
+
using Rice_Arg_Tuple = std::tuple<Rice_Arg_Ts...>;
|
|
14864
|
+
constexpr std::size_t arg_index = detail::tuple_element_index_v<Rice_Arg_Tuple, Arg>;
|
|
14865
|
+
|
|
14866
|
+
if constexpr (arg_index < sizeof...(Rice_Arg_Ts))
|
|
14867
|
+
{
|
|
14868
|
+
// User provided an Arg - extract it and ensure setValue is set
|
|
14869
|
+
Arg arg = std::get<arg_index>(std::forward_as_tuple(args...));
|
|
14870
|
+
arg.setValue();
|
|
14871
|
+
this->define_method("initialize_copy", &Constructor_T::initialize_copy, arg);
|
|
14872
|
+
}
|
|
14873
|
+
else
|
|
14874
|
+
{
|
|
14875
|
+
this->define_method("initialize_copy", &Constructor_T::initialize_copy, Arg("other").setValue());
|
|
14876
|
+
}
|
|
14373
14877
|
}
|
|
14374
14878
|
else if constexpr (Constructor_T::isMoveConstructor())
|
|
14375
14879
|
{
|
|
@@ -14384,14 +14888,6 @@ namespace Rice4RubyQt6
|
|
|
14384
14888
|
return *this;
|
|
14385
14889
|
}
|
|
14386
14890
|
|
|
14387
|
-
template<typename T>
|
|
14388
|
-
template<typename Function_T>
|
|
14389
|
-
inline Data_Type<T>& Data_Type<T>::define(Function_T func)
|
|
14390
|
-
{
|
|
14391
|
-
func(*this);
|
|
14392
|
-
return *this;
|
|
14393
|
-
}
|
|
14394
|
-
|
|
14395
14891
|
template<typename T>
|
|
14396
14892
|
template<typename Director_T>
|
|
14397
14893
|
inline Data_Type<T>& Data_Type<T>::define_director()
|
|
@@ -14431,8 +14927,7 @@ namespace Rice4RubyQt6
|
|
|
14431
14927
|
{
|
|
14432
14928
|
if (!is_bound())
|
|
14433
14929
|
{
|
|
14434
|
-
|
|
14435
|
-
std::string message = "Type is not defined with Rice: " + typeIndexParser.name();
|
|
14930
|
+
std::string message = "Type is not defined with Rice: " + detail::TypeDetail<T>().name();
|
|
14436
14931
|
throw std::invalid_argument(message.c_str());
|
|
14437
14932
|
}
|
|
14438
14933
|
}
|
|
@@ -14469,7 +14964,7 @@ namespace Rice4RubyQt6
|
|
|
14469
14964
|
}
|
|
14470
14965
|
else
|
|
14471
14966
|
{
|
|
14472
|
-
// This gives a chance
|
|
14967
|
+
// This gives a chance to auto-register classes such as std::exception
|
|
14473
14968
|
detail::verifyType<Base_T>();
|
|
14474
14969
|
result = Data_Type<Base_T>::klass();
|
|
14475
14970
|
}
|
|
@@ -14514,6 +15009,19 @@ namespace Rice4RubyQt6
|
|
|
14514
15009
|
return Data_Type<T>::template bind<Base_T>(klass);
|
|
14515
15010
|
}
|
|
14516
15011
|
|
|
15012
|
+
template<typename T, typename Base_T>
|
|
15013
|
+
Data_Type<T> declare_class_under(Object parent, char const* name, rb_data_type_t *data_type)
|
|
15014
|
+
{
|
|
15015
|
+
Identifier id(name);
|
|
15016
|
+
if (Rice4RubyQt6::Data_Type<T>::check_defined(id.str(), parent))
|
|
15017
|
+
{
|
|
15018
|
+
return Data_Type<T>();
|
|
15019
|
+
}
|
|
15020
|
+
|
|
15021
|
+
Class klass = parent.const_get(id).value();
|
|
15022
|
+
return Data_Type<T>::template bind<Base_T>(klass, data_type);
|
|
15023
|
+
}
|
|
15024
|
+
|
|
14517
15025
|
template<typename T>
|
|
14518
15026
|
template<typename Iterator_Func_T>
|
|
14519
15027
|
inline Data_Type<T>& Data_Type<T>::define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name)
|
|
@@ -14528,61 +15036,34 @@ namespace Rice4RubyQt6
|
|
|
14528
15036
|
}
|
|
14529
15037
|
|
|
14530
15038
|
template <typename T>
|
|
14531
|
-
template <typename Attribute_T, typename...Arg_Ts>
|
|
14532
|
-
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name, Attribute_T attribute,
|
|
15039
|
+
template <typename Attribute_T, typename Access_T, typename...Arg_Ts>
|
|
15040
|
+
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name, Attribute_T attribute, Access_T access, const Arg_Ts&...args)
|
|
14533
15041
|
{
|
|
14534
|
-
return this->define_attr_internal<Attribute_T>(this->klass_, name, std::forward<Attribute_T>(attribute), access, args...);
|
|
15042
|
+
return this->define_attr_internal<Attribute_T, Access_T>(this->klass_, name, std::forward<Attribute_T>(attribute), access, args...);
|
|
14535
15043
|
}
|
|
14536
15044
|
|
|
14537
15045
|
template <typename T>
|
|
14538
|
-
template <typename Attribute_T, typename...Arg_Ts>
|
|
14539
|
-
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute,
|
|
15046
|
+
template <typename Attribute_T, typename Access_T, typename...Arg_Ts>
|
|
15047
|
+
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute, Access_T access, const Arg_Ts&...args)
|
|
14540
15048
|
{
|
|
14541
|
-
VALUE singleton = detail::protect(rb_singleton_class, this->
|
|
14542
|
-
return this->define_attr_internal<Attribute_T>(singleton, name, std::forward<Attribute_T>(attribute), access, args...);
|
|
15049
|
+
VALUE singleton = detail::protect(rb_singleton_class, this->validated_value());
|
|
15050
|
+
return this->define_attr_internal<Attribute_T, Access_T>(singleton, name, std::forward<Attribute_T>(attribute), access, args...);
|
|
14543
15051
|
}
|
|
14544
15052
|
|
|
14545
15053
|
template <typename T>
|
|
14546
|
-
template <typename Attribute_T, typename...Arg_Ts>
|
|
14547
|
-
inline Data_Type<T>& Data_Type<T>::define_attr_internal(VALUE klass, std::string name, Attribute_T attribute,
|
|
15054
|
+
template <typename Attribute_T, typename Access_T, typename...Arg_Ts>
|
|
15055
|
+
inline Data_Type<T>& Data_Type<T>::define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, Access_T, const Arg_Ts&...args)
|
|
14548
15056
|
{
|
|
14549
|
-
using Attr_T = typename detail::attribute_traits<Attribute_T>::attr_type;
|
|
14550
|
-
|
|
14551
15057
|
// Define attribute getter
|
|
14552
|
-
if (
|
|
15058
|
+
if constexpr (std::is_same_v<Access_T, AttrAccess::ReadWriteType> || std::is_same_v<Access_T, AttrAccess::ReadType>)
|
|
14553
15059
|
{
|
|
14554
15060
|
detail::NativeAttributeGet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), args...);
|
|
14555
15061
|
}
|
|
14556
15062
|
|
|
14557
15063
|
// Define attribute setter
|
|
14558
|
-
|
|
14559
|
-
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
|
15064
|
+
if constexpr (std::is_same_v<Access_T, AttrAccess::ReadWriteType> || std::is_same_v<Access_T, AttrAccess::WriteType>)
|
|
14560
15065
|
{
|
|
14561
|
-
|
|
14562
|
-
constexpr bool checkWriteAccess = !std::is_reference_v<Attr_T> &&
|
|
14563
|
-
!std::is_pointer_v<Attr_T> &&
|
|
14564
|
-
!std::is_fundamental_v<Attr_T> &&
|
|
14565
|
-
!std::is_enum_v<Attr_T>;
|
|
14566
|
-
|
|
14567
|
-
if constexpr (std::is_const_v<Attr_T>)
|
|
14568
|
-
{
|
|
14569
|
-
throw std::runtime_error("Cannot define attribute writer for a const attribute: " + name);
|
|
14570
|
-
}
|
|
14571
|
-
// Attributes are set using assignment operator like this:
|
|
14572
|
-
// myInstance.attribute = newvalue
|
|
14573
|
-
else if constexpr (checkWriteAccess && !std::is_assignable_v<Attr_T, Attr_T>)
|
|
14574
|
-
{
|
|
14575
|
-
throw std::runtime_error("Cannot define attribute writer for a non assignable attribute: " + name);
|
|
14576
|
-
}
|
|
14577
|
-
// From_Ruby returns a copy of the value for non-reference and non-pointers, thus needs to be copy constructable
|
|
14578
|
-
else if constexpr (checkWriteAccess && !std::is_copy_constructible_v<Attr_T>)
|
|
14579
|
-
{
|
|
14580
|
-
throw std::runtime_error("Cannot define attribute writer for a non copy constructible attribute: " + name);
|
|
14581
|
-
}
|
|
14582
|
-
else
|
|
14583
|
-
{
|
|
14584
|
-
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), args...);
|
|
14585
|
-
}
|
|
15066
|
+
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), args...);
|
|
14586
15067
|
}
|
|
14587
15068
|
|
|
14588
15069
|
return *this;
|
|
@@ -14655,11 +15136,14 @@ namespace Rice4RubyQt6
|
|
|
14655
15136
|
detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data);
|
|
14656
15137
|
}
|
|
14657
15138
|
|
|
14658
|
-
|
|
15139
|
+
// Takes VALUE (via Arg.setValue()) instead of const T& so we have access to
|
|
15140
|
+
// both Ruby wrappers and can copy the keepAlive list from the original to the clone.
|
|
15141
|
+
static VALUE initialize_copy(VALUE self, VALUE other)
|
|
14659
15142
|
{
|
|
14660
|
-
|
|
14661
|
-
T* data = new T(
|
|
14662
|
-
detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data);
|
|
15143
|
+
T* otherData = detail::unwrap<T>(other, Data_Type<T>::ruby_data_type(), false);
|
|
15144
|
+
T* data = new T(*otherData);
|
|
15145
|
+
detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data, other);
|
|
15146
|
+
return self;
|
|
14663
15147
|
}
|
|
14664
15148
|
|
|
14665
15149
|
};
|
|
@@ -14733,9 +15217,8 @@ namespace Rice4RubyQt6
|
|
|
14733
15217
|
}
|
|
14734
15218
|
else
|
|
14735
15219
|
{
|
|
14736
|
-
detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
|
|
14737
15220
|
return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
|
|
14738
|
-
|
|
15221
|
+
detail::TypeDetail<T>().name().c_str(),
|
|
14739
15222
|
detail::protect(rb_obj_classname, value));
|
|
14740
15223
|
}
|
|
14741
15224
|
}
|
|
@@ -14804,7 +15287,7 @@ namespace Rice4RubyQt6
|
|
|
14804
15287
|
template<typename T>
|
|
14805
15288
|
inline T* Data_Object<T>::get() const
|
|
14806
15289
|
{
|
|
14807
|
-
if (this->
|
|
15290
|
+
if (this->is_nil())
|
|
14808
15291
|
{
|
|
14809
15292
|
return nullptr;
|
|
14810
15293
|
}
|
|
@@ -15234,10 +15717,14 @@ namespace Rice4RubyQt6::detail
|
|
|
15234
15717
|
{
|
|
15235
15718
|
return Convertible::Exact;
|
|
15236
15719
|
}
|
|
15237
|
-
else if (Data_Type<Pointer_T>::is_descendant(value))
|
|
15720
|
+
else if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
|
|
15238
15721
|
{
|
|
15239
15722
|
return Convertible::Exact;
|
|
15240
15723
|
}
|
|
15724
|
+
else if (Data_Type<Pointer_T>::is_descendant(value) && !isBuffer)
|
|
15725
|
+
{
|
|
15726
|
+
return Convertible::Exact * 0.99;
|
|
15727
|
+
}
|
|
15241
15728
|
[[fallthrough]];
|
|
15242
15729
|
default:
|
|
15243
15730
|
return Convertible::None;
|
|
@@ -15354,15 +15841,13 @@ namespace Rice4RubyQt6::detail
|
|
|
15354
15841
|
|
|
15355
15842
|
double is_convertible(VALUE value)
|
|
15356
15843
|
{
|
|
15357
|
-
bool isBuffer = dynamic_cast<ArgBuffer*>(this->arg_) ? true : false;
|
|
15358
|
-
|
|
15359
15844
|
switch (rb_type(value))
|
|
15360
15845
|
{
|
|
15361
15846
|
case RUBY_T_NIL:
|
|
15362
15847
|
return Convertible::Exact;
|
|
15363
15848
|
break;
|
|
15364
15849
|
case RUBY_T_DATA:
|
|
15365
|
-
if (Data_Type<Pointer_T>::is_descendant(value)
|
|
15850
|
+
if (Data_Type<Pointer_T>::is_descendant(value))
|
|
15366
15851
|
{
|
|
15367
15852
|
return Convertible::Exact;
|
|
15368
15853
|
}
|
|
@@ -15375,7 +15860,6 @@ namespace Rice4RubyQt6::detail
|
|
|
15375
15860
|
T** convert(VALUE value)
|
|
15376
15861
|
{
|
|
15377
15862
|
bool isOwner = this->arg_ && this->arg_->isOwner();
|
|
15378
|
-
bool isBuffer = dynamic_cast<ArgBuffer*>(this->arg_) ? true : false;
|
|
15379
15863
|
|
|
15380
15864
|
switch (rb_type(value))
|
|
15381
15865
|
{
|
|
@@ -15386,7 +15870,7 @@ namespace Rice4RubyQt6::detail
|
|
|
15386
15870
|
}
|
|
15387
15871
|
case RUBY_T_DATA:
|
|
15388
15872
|
{
|
|
15389
|
-
if (Data_Type<Pointer_T>::is_descendant(value)
|
|
15873
|
+
if (Data_Type<Pointer_T>::is_descendant(value))
|
|
15390
15874
|
{
|
|
15391
15875
|
T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
|
|
15392
15876
|
return result;
|
|
@@ -15395,14 +15879,7 @@ namespace Rice4RubyQt6::detail
|
|
|
15395
15879
|
}
|
|
15396
15880
|
default:
|
|
15397
15881
|
{
|
|
15398
|
-
|
|
15399
|
-
{
|
|
15400
|
-
throw create_type_exception<Pointer_T>(value);
|
|
15401
|
-
}
|
|
15402
|
-
else
|
|
15403
|
-
{
|
|
15404
|
-
throw create_type_exception<T**>(value);
|
|
15405
|
-
}
|
|
15882
|
+
throw create_type_exception<Pointer_T>(value);
|
|
15406
15883
|
}
|
|
15407
15884
|
}
|
|
15408
15885
|
}
|
|
@@ -15721,7 +16198,7 @@ namespace Rice4RubyQt6
|
|
|
15721
16198
|
// These methods cannot be defined where they are declared due to circular dependencies
|
|
15722
16199
|
inline Class Object::class_of() const
|
|
15723
16200
|
{
|
|
15724
|
-
return detail::protect(rb_class_of,
|
|
16201
|
+
return detail::protect(rb_class_of, this->value());
|
|
15725
16202
|
}
|
|
15726
16203
|
|
|
15727
16204
|
inline String Object::to_s() const
|
|
@@ -15801,86 +16278,6 @@ namespace Rice4RubyQt6
|
|
|
15801
16278
|
}
|
|
15802
16279
|
}
|
|
15803
16280
|
|
|
15804
|
-
// Dependent on Module, Array, Symbol - used by stl smart pointers
|
|
15805
|
-
|
|
15806
|
-
// ========= Forwards.hpp =========
|
|
15807
|
-
|
|
15808
|
-
namespace Rice4RubyQt6::detail
|
|
15809
|
-
{
|
|
15810
|
-
// Setup method forwarding from a wrapper class to its wrapped type using Ruby's Forwardable.
|
|
15811
|
-
// This allows calling methods on the wrapper that get delegated to the wrapped object via
|
|
15812
|
-
// a "get" method that returns the wrapped object.
|
|
15813
|
-
//
|
|
15814
|
-
// Parameters:
|
|
15815
|
-
// wrapper_klass - The Ruby class to add forwarding to (e.g., SharedPtr_MyClass)
|
|
15816
|
-
// wrapped_klass - The Ruby class whose methods should be forwarded (e.g., MyClass)
|
|
15817
|
-
void define_forwarding(VALUE wrapper_klass, VALUE wrapped_klass);
|
|
15818
|
-
}
|
|
15819
|
-
|
|
15820
|
-
|
|
15821
|
-
// --------- Forwards.ipp ---------
|
|
15822
|
-
namespace Rice4RubyQt6::detail
|
|
15823
|
-
{
|
|
15824
|
-
inline void define_forwarding(VALUE wrapper_klass, VALUE wrapped_klass)
|
|
15825
|
-
{
|
|
15826
|
-
protect(rb_require, "forwardable");
|
|
15827
|
-
Object forwardable = Object(rb_cObject).const_get("Forwardable");
|
|
15828
|
-
Object(wrapper_klass).extend(forwardable.value());
|
|
15829
|
-
|
|
15830
|
-
// Get wrapper class's method names to avoid conflicts
|
|
15831
|
-
std::set<std::string> wrapperMethodSet;
|
|
15832
|
-
for (Native* native : Registries::instance.natives.lookup(wrapper_klass, NativeKind::Method))
|
|
15833
|
-
{
|
|
15834
|
-
wrapperMethodSet.insert(native->name());
|
|
15835
|
-
}
|
|
15836
|
-
for (Native* native : Registries::instance.natives.lookup(wrapper_klass, NativeKind::AttributeReader))
|
|
15837
|
-
{
|
|
15838
|
-
wrapperMethodSet.insert(native->name());
|
|
15839
|
-
}
|
|
15840
|
-
for (Native* native : Registries::instance.natives.lookup(wrapper_klass, NativeKind::AttributeWriter))
|
|
15841
|
-
{
|
|
15842
|
-
wrapperMethodSet.insert(native->name() + "=");
|
|
15843
|
-
}
|
|
15844
|
-
|
|
15845
|
-
// Get wrapped class's method names from the registry, including ancestor classes
|
|
15846
|
-
std::set<std::string> wrappedMethodSet;
|
|
15847
|
-
Class klass(wrapped_klass);
|
|
15848
|
-
while (klass.value() != rb_cObject && klass.value() != Qnil)
|
|
15849
|
-
{
|
|
15850
|
-
for (Native* native : Registries::instance.natives.lookup(klass.value(), NativeKind::Method))
|
|
15851
|
-
{
|
|
15852
|
-
wrappedMethodSet.insert(native->name());
|
|
15853
|
-
}
|
|
15854
|
-
for (Native* native : Registries::instance.natives.lookup(klass.value(), NativeKind::AttributeReader))
|
|
15855
|
-
{
|
|
15856
|
-
wrappedMethodSet.insert(native->name());
|
|
15857
|
-
}
|
|
15858
|
-
for (Native* native : Registries::instance.natives.lookup(klass.value(), NativeKind::AttributeWriter))
|
|
15859
|
-
{
|
|
15860
|
-
wrappedMethodSet.insert(native->name() + "=");
|
|
15861
|
-
}
|
|
15862
|
-
|
|
15863
|
-
klass = klass.superclass();
|
|
15864
|
-
}
|
|
15865
|
-
|
|
15866
|
-
// Build the arguments array for def_delegators: [:get, :method1, :method2, ...]
|
|
15867
|
-
// Skip methods that are already defined on the wrapper class
|
|
15868
|
-
Array args;
|
|
15869
|
-
args.push(Symbol("get"));
|
|
15870
|
-
for (const std::string& method : wrappedMethodSet)
|
|
15871
|
-
{
|
|
15872
|
-
if (wrapperMethodSet.find(method) == wrapperMethodSet.end())
|
|
15873
|
-
{
|
|
15874
|
-
args.push(Symbol(method));
|
|
15875
|
-
}
|
|
15876
|
-
}
|
|
15877
|
-
|
|
15878
|
-
// Call def_delegators(*args)
|
|
15879
|
-
Object(wrapper_klass).vcall("def_delegators", args);
|
|
15880
|
-
}
|
|
15881
|
-
}
|
|
15882
|
-
|
|
15883
|
-
|
|
15884
16281
|
// For now include libc support - maybe should be separate header file someday
|
|
15885
16282
|
|
|
15886
16283
|
// ========= file.hpp =========
|