rice 4.3.2 → 4.5.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/CHANGELOG.md +66 -25
- data/README.md +7 -2
- data/Rakefile +7 -1
- data/include/rice/rice.hpp +7321 -4470
- data/include/rice/stl.hpp +769 -222
- data/lib/mkmf-rice.rb +37 -95
- data/rice/Address_Registration_Guard.hpp +72 -3
- data/rice/Arg.hpp +19 -5
- data/rice/Arg.ipp +24 -0
- data/rice/Callback.hpp +21 -0
- data/rice/Callback.ipp +13 -0
- data/rice/Constructor.hpp +4 -27
- data/rice/Constructor.ipp +79 -0
- data/rice/Data_Object.hpp +74 -3
- data/rice/Data_Object.ipp +324 -32
- data/rice/Data_Type.hpp +215 -3
- data/rice/Data_Type.ipp +125 -64
- data/rice/Director.hpp +0 -2
- data/rice/Enum.hpp +4 -6
- data/rice/Enum.ipp +101 -57
- data/rice/Exception.hpp +62 -2
- data/rice/Exception.ipp +7 -12
- data/rice/JumpException.hpp +44 -0
- data/rice/JumpException.ipp +48 -0
- data/rice/MemoryView.hpp +11 -0
- data/rice/MemoryView.ipp +43 -0
- data/rice/Return.hpp +6 -26
- data/rice/Return.ipp +10 -16
- data/rice/detail/DefaultHandler.hpp +12 -0
- data/rice/detail/DefaultHandler.ipp +8 -0
- data/rice/detail/HandlerRegistry.hpp +5 -35
- data/rice/detail/HandlerRegistry.ipp +7 -11
- data/rice/detail/InstanceRegistry.hpp +1 -4
- data/rice/detail/MethodInfo.hpp +15 -5
- data/rice/detail/MethodInfo.ipp +78 -6
- data/rice/detail/Native.hpp +32 -0
- data/rice/detail/Native.ipp +129 -0
- data/rice/detail/NativeAttributeGet.hpp +51 -0
- data/rice/detail/NativeAttributeGet.ipp +51 -0
- data/rice/detail/NativeAttributeSet.hpp +43 -0
- data/rice/detail/NativeAttributeSet.ipp +82 -0
- data/rice/detail/NativeCallbackFFI.hpp +55 -0
- data/rice/detail/NativeCallbackFFI.ipp +151 -0
- data/rice/detail/NativeCallbackSimple.hpp +30 -0
- data/rice/detail/NativeCallbackSimple.ipp +29 -0
- data/rice/detail/NativeFunction.hpp +20 -21
- data/rice/detail/NativeFunction.ipp +199 -64
- data/rice/detail/NativeIterator.hpp +8 -11
- data/rice/detail/NativeIterator.ipp +27 -31
- data/rice/detail/NativeRegistry.hpp +24 -17
- data/rice/detail/NativeRegistry.ipp +23 -56
- data/rice/detail/Proc.hpp +4 -0
- data/rice/detail/Proc.ipp +85 -0
- data/rice/detail/Registries.hpp +0 -7
- data/rice/detail/Registries.ipp +0 -18
- data/rice/detail/RubyFunction.hpp +0 -3
- data/rice/detail/RubyFunction.ipp +4 -8
- data/rice/detail/RubyType.hpp +19 -0
- data/rice/detail/RubyType.ipp +187 -0
- data/rice/detail/TupleIterator.hpp +14 -0
- data/rice/detail/Type.hpp +5 -6
- data/rice/detail/Type.ipp +150 -33
- data/rice/detail/TypeRegistry.hpp +15 -7
- data/rice/detail/TypeRegistry.ipp +105 -12
- data/rice/detail/Wrapper.hpp +6 -5
- data/rice/detail/Wrapper.ipp +45 -23
- data/rice/detail/cpp_protect.hpp +5 -6
- data/rice/detail/default_allocation_func.ipp +0 -2
- data/rice/detail/from_ruby.hpp +37 -3
- data/rice/detail/from_ruby.ipp +911 -454
- data/rice/detail/ruby.hpp +18 -0
- data/rice/detail/to_ruby.hpp +41 -3
- data/rice/detail/to_ruby.ipp +437 -113
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +1 -2
- data/rice/rice.hpp +105 -22
- data/rice/ruby_mark.hpp +4 -3
- data/rice/stl.hpp +4 -0
- data/test/embed_ruby.cpp +4 -1
- data/test/extconf.rb +2 -0
- data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
- data/test/test_Address_Registration_Guard.cpp +5 -0
- data/test/test_Array.cpp +12 -1
- data/test/test_Attribute.cpp +103 -21
- data/test/test_Builtin_Object.cpp +5 -0
- data/test/test_Callback.cpp +231 -0
- data/test/test_Class.cpp +5 -31
- data/test/test_Constructor.cpp +69 -6
- data/test/test_Data_Object.cpp +9 -4
- data/test/test_Data_Type.cpp +428 -64
- data/test/test_Director.cpp +10 -5
- data/test/test_Enum.cpp +152 -40
- data/test/test_Exception.cpp +235 -0
- data/test/test_File.cpp +70 -0
- data/test/test_From_Ruby.cpp +542 -0
- data/test/test_Hash.cpp +5 -0
- data/test/test_Identifier.cpp +5 -0
- data/test/test_Inheritance.cpp +6 -1
- data/test/test_Iterator.cpp +5 -0
- data/test/test_JumpException.cpp +22 -0
- data/test/test_Keep_Alive.cpp +6 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -0
- data/test/test_Memory_Management.cpp +5 -0
- data/test/test_Module.cpp +118 -64
- data/test/test_Native_Registry.cpp +2 -33
- data/test/test_Object.cpp +5 -0
- data/test/test_Overloads.cpp +631 -0
- data/test/test_Ownership.cpp +67 -4
- data/test/test_Proc.cpp +45 -0
- data/test/test_Self.cpp +5 -0
- data/test/test_Stl_Exception.cpp +109 -0
- data/test/test_Stl_Map.cpp +22 -8
- data/test/test_Stl_Optional.cpp +5 -0
- data/test/test_Stl_Pair.cpp +7 -2
- data/test/test_Stl_Reference_Wrapper.cpp +5 -0
- data/test/test_Stl_SmartPointer.cpp +210 -5
- data/test/test_Stl_String.cpp +5 -0
- data/test/test_Stl_String_View.cpp +5 -0
- data/test/test_Stl_Type.cpp +147 -0
- data/test/test_Stl_Unordered_Map.cpp +18 -7
- data/test/test_Stl_Variant.cpp +5 -0
- data/test/test_Stl_Vector.cpp +130 -8
- data/test/test_String.cpp +5 -0
- data/test/test_Struct.cpp +5 -0
- data/test/test_Symbol.cpp +5 -0
- data/test/test_Template.cpp +192 -0
- data/test/test_To_Ruby.cpp +152 -0
- data/test/test_Tracking.cpp +1 -0
- data/test/test_Type.cpp +100 -0
- data/test/test_global_functions.cpp +53 -6
- data/test/unittest.cpp +8 -0
- metadata +37 -20
- data/lib/version.rb +0 -3
- data/rice/Address_Registration_Guard_defn.hpp +0 -79
- data/rice/Data_Object_defn.hpp +0 -84
- data/rice/Data_Type_defn.hpp +0 -190
- data/rice/Exception_defn.hpp +0 -68
- data/rice/HandlerRegistration.hpp +0 -15
- data/rice/Identifier.hpp +0 -50
- data/rice/Identifier.ipp +0 -29
- data/rice/detail/ExceptionHandler.hpp +0 -8
- data/rice/detail/ExceptionHandler.ipp +0 -28
- data/rice/detail/ExceptionHandler_defn.hpp +0 -77
- data/rice/detail/Jump_Tag.hpp +0 -21
- data/rice/detail/NativeAttribute.hpp +0 -64
- data/rice/detail/NativeAttribute.ipp +0 -112
- data/rice/detail/from_ruby_defn.hpp +0 -38
- data/rice/detail/to_ruby_defn.hpp +0 -48
- data/test/test_Jump_Tag.cpp +0 -17
- data/test/test_To_From_Ruby.cpp +0 -399
data/lib/mkmf-rice.rb
CHANGED
@@ -1,93 +1,8 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
-
IS_MSWIN =
|
4
|
-
IS_MINGW =
|
5
|
-
IS_DARWIN =
|
6
|
-
|
7
|
-
# If we are on versions of Ruby before 2.7 then we need to copy in the experimental C++ support
|
8
|
-
# added in Ruby 2.7
|
9
|
-
unless MakeMakefile.methods.include?(:[])
|
10
|
-
|
11
|
-
# Ruby 2.6 makes this declaration which is not valid with C++17
|
12
|
-
# void rb_mem_clear(register VALUE*, register long);
|
13
|
-
if !IS_MSWIN
|
14
|
-
$CXXFLAGS += " " << "-Wno-register"
|
15
|
-
end
|
16
|
-
|
17
|
-
MakeMakefile::CONFTEST_C = "#{CONFTEST}.cc"
|
18
|
-
|
19
|
-
MakeMakefile.module_eval do
|
20
|
-
CONFTEST_C = "#{CONFTEST}.cc"
|
21
|
-
def cc_config(opt="")
|
22
|
-
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
|
23
|
-
'arch_hdrdir' => $arch_hdrdir.quote,
|
24
|
-
'top_srcdir' => $top_srcdir.quote)
|
25
|
-
conf
|
26
|
-
end
|
27
|
-
|
28
|
-
def link_config(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
|
29
|
-
librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
|
30
|
-
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
|
31
|
-
'src' => "#{conftest_source}",
|
32
|
-
'arch_hdrdir' => $arch_hdrdir.quote,
|
33
|
-
'top_srcdir' => $top_srcdir.quote,
|
34
|
-
'INCFLAGS' => "#$INCFLAGS",
|
35
|
-
'CPPFLAGS' => "#$CPPFLAGS",
|
36
|
-
'CFLAGS' => "#$CFLAGS",
|
37
|
-
'ARCH_FLAG' => "#$ARCH_FLAG",
|
38
|
-
'LDFLAGS' => "#$LDFLAGS #{ldflags}",
|
39
|
-
'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
|
40
|
-
'LIBS' => "#{librubyarg} #{opt} #$LIBS")
|
41
|
-
conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
|
42
|
-
conf
|
43
|
-
end
|
44
|
-
|
45
|
-
@lang = Hash.new(self)
|
46
|
-
|
47
|
-
def self.[](name)
|
48
|
-
@lang.fetch(name)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.[]=(name, mod)
|
52
|
-
@lang[name] = mod
|
53
|
-
end
|
54
|
-
|
55
|
-
MakeMakefile["C++"] = Module.new do
|
56
|
-
include MakeMakefile
|
57
|
-
extend self
|
58
|
-
|
59
|
-
CONFTEST_CXX = "#{CONFTEST}.#{config_string('CXX_EXT') || CXX_EXT[0]}"
|
60
|
-
|
61
|
-
TRY_LINK_CXX = config_string('TRY_LINK_CXX') ||
|
62
|
-
((cmd = TRY_LINK.gsub(/\$\(C(?:C|(FLAGS))\)/, '$(CXX\1)')) != TRY_LINK && cmd) ||
|
63
|
-
"$(CXX) #{OUTFLAG}#{CONFTEST}#{$EXEEXT} $(INCFLAGS) $(CPPFLAGS) " \
|
64
|
-
"$(CXXFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
|
65
|
-
|
66
|
-
def have_devel?
|
67
|
-
unless defined? @have_devel
|
68
|
-
@have_devel = true
|
69
|
-
@have_devel = try_link(MAIN_DOES_NOTHING)
|
70
|
-
end
|
71
|
-
@have_devel
|
72
|
-
end
|
73
|
-
|
74
|
-
def conftest_source
|
75
|
-
CONFTEST_CXX
|
76
|
-
end
|
77
|
-
|
78
|
-
def cc_command(opt="")
|
79
|
-
conf = cc_config(opt)
|
80
|
-
RbConfig::expand("$(CXX) #$INCFLAGS #$CPPFLAGS #$CXXFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_CXX}",
|
81
|
-
conf)
|
82
|
-
end
|
83
|
-
|
84
|
-
def link_command(ldflags, *opts)
|
85
|
-
conf = link_config(ldflags, *opts)
|
86
|
-
RbConfig::expand(TRY_LINK_CXX.dup, conf)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
3
|
+
IS_MSWIN = /mswin/ =~ RUBY_PLATFORM
|
4
|
+
IS_MINGW = /mingw/ =~ RUBY_PLATFORM
|
5
|
+
IS_DARWIN = RbConfig::CONFIG['host_os'].match?(/darwin/)
|
91
6
|
|
92
7
|
# The cpp_command is not overwritten in the experimental mkmf C++ support.
|
93
8
|
# See https://bugs.ruby-lang.org/issues/17578
|
@@ -107,7 +22,7 @@ include MakeMakefile['C++']
|
|
107
22
|
|
108
23
|
# Rice needs c++17.
|
109
24
|
if IS_MSWIN
|
110
|
-
$CXXFLAGS += " /std:c++17 /
|
25
|
+
$CXXFLAGS += " /std:c++17 /EHs /permissive- /bigobj /utf-8"
|
111
26
|
$CPPFLAGS += " -D_ALLOW_KEYWORD_MACROS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE"
|
112
27
|
elsif IS_MINGW
|
113
28
|
$CXXFLAGS += " -std=c++17 -Wa,-mbig-obj"
|
@@ -123,10 +38,37 @@ unless find_header('rice/rice.hpp', path)
|
|
123
38
|
raise("Could not find rice/rice.hpp header")
|
124
39
|
end
|
125
40
|
|
126
|
-
if IS_DARWIN
|
127
|
-
have_library('
|
128
|
-
|
129
|
-
|
130
|
-
|
41
|
+
if !IS_DARWIN && !IS_MSWIN && !have_library('stdc++fs')
|
42
|
+
have_library('stdc++')
|
43
|
+
end
|
44
|
+
|
45
|
+
# Copied from Ruby FFI bindings - see
|
46
|
+
# https://github.com/ffi/ffi/blob/1715332d553d53fae13fd9fcbbd9d2c1982a5c2f/ext/ffi_c/extconf.rb#L7C1-L27C6
|
47
|
+
def system_libffi_usable?
|
48
|
+
# We need pkg_config or ffi.h
|
49
|
+
libffi_ok = pkg_config("libffi") ||
|
50
|
+
have_header("ffi.h") ||
|
51
|
+
find_header("ffi.h", "/usr/local/include", "/usr/include/ffi",
|
52
|
+
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ffi",
|
53
|
+
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ffi") ||
|
54
|
+
(find_header("ffi.h", `xcrun --sdk macosx --show-sdk-path`.strip + "/usr/include/ffi") rescue false)
|
55
|
+
|
56
|
+
# Ensure we can link to ffi_prep_closure_loc
|
57
|
+
libffi_ok &&= have_library("ffi", "ffi_prep_closure_loc", [ "ffi.h" ]) ||
|
58
|
+
have_library("libffi", "ffi_prep_closure_loc", [ "ffi.h" ]) ||
|
59
|
+
have_library("libffi-8", "ffi_prep_closure_loc", [ "ffi.h" ])
|
60
|
+
|
61
|
+
if RbConfig::CONFIG['host_os'] =~ /mswin/
|
62
|
+
have_library('libffi_convenience')
|
63
|
+
have_library('shlwapi')
|
131
64
|
end
|
132
|
-
|
65
|
+
|
66
|
+
libffi_ok
|
67
|
+
end
|
68
|
+
|
69
|
+
def have_libffi
|
70
|
+
# Check for libffi to support C style callacks.
|
71
|
+
libffi_usable = system_libffi_usable?
|
72
|
+
$CPPFLAGS += " -DHAVE_LIBFFI" if libffi_usable
|
73
|
+
libffi_usable
|
74
|
+
end
|
@@ -1,7 +1,76 @@
|
|
1
1
|
#ifndef Rice__Address_Registration_Guard__hpp_
|
2
2
|
#define Rice__Address_Registration_Guard__hpp_
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
namespace Rice
|
5
|
+
{
|
6
|
+
//! A guard to register a given address with the GC.
|
7
|
+
/*! Calls rb_gc_register_address upon construction and
|
8
|
+
* rb_gc_unregister_address upon destruction.
|
9
|
+
* For example:
|
10
|
+
* \code
|
11
|
+
* Class Foo
|
12
|
+
* {
|
13
|
+
* public:
|
14
|
+
* Foo()
|
15
|
+
* : string_(rb_str_new2())
|
16
|
+
* , guard_(&string_);
|
17
|
+
*
|
18
|
+
* private:
|
19
|
+
* VALUE string_;
|
20
|
+
* Address_Registration_Guard guard_;
|
21
|
+
* };
|
22
|
+
* \endcode
|
23
|
+
*/
|
24
|
+
class Address_Registration_Guard
|
25
|
+
{
|
26
|
+
public:
|
27
|
+
//! Register an address with the GC.
|
28
|
+
/* \param address The address to register with the GC. The address
|
29
|
+
* must point to a valid ruby object (RObject).
|
30
|
+
*/
|
31
|
+
Address_Registration_Guard(VALUE* address);
|
6
32
|
|
7
|
-
|
33
|
+
//! Register an Object with the GC.
|
34
|
+
/*! \param object The Object to register with the GC. The object must
|
35
|
+
* not be destroyed before the Address_Registration_Guard is
|
36
|
+
* destroyed.
|
37
|
+
*/
|
38
|
+
Address_Registration_Guard(Object* object);
|
39
|
+
|
40
|
+
//! Unregister an address/Object with the GC.
|
41
|
+
/*! Destruct an Address_Registration_Guard. The address registered
|
42
|
+
* with the Address_Registration_Guard when it was constructed will
|
43
|
+
* be unregistered from the GC.
|
44
|
+
*/
|
45
|
+
~Address_Registration_Guard();
|
46
|
+
|
47
|
+
// Disable copying
|
48
|
+
Address_Registration_Guard(Address_Registration_Guard const& other) = delete;
|
49
|
+
Address_Registration_Guard& operator=(Address_Registration_Guard const& other) = delete;
|
50
|
+
|
51
|
+
// Enable moving
|
52
|
+
Address_Registration_Guard(Address_Registration_Guard&& other);
|
53
|
+
Address_Registration_Guard& operator=(Address_Registration_Guard&& other);
|
54
|
+
|
55
|
+
//! Get the address that is registered with the GC.
|
56
|
+
VALUE* address() const;
|
57
|
+
|
58
|
+
/** Called during Ruby's exit process since we should not call
|
59
|
+
* rb_gc unregister_address there
|
60
|
+
*/
|
61
|
+
static void disable();
|
62
|
+
|
63
|
+
private:
|
64
|
+
inline static bool enabled = true;
|
65
|
+
inline static bool exit_handler_registered = false;
|
66
|
+
static void registerExitHandler();
|
67
|
+
|
68
|
+
private:
|
69
|
+
void registerAddress() const;
|
70
|
+
void unregisterAddress();
|
71
|
+
|
72
|
+
VALUE* address_ = nullptr;
|
73
|
+
};
|
74
|
+
} // namespace Rice
|
75
|
+
|
76
|
+
#endif // Rice__Address_Registration_Guard__hpp_
|
data/rice/Arg.hpp
CHANGED
@@ -35,6 +35,9 @@ namespace Rice
|
|
35
35
|
*/
|
36
36
|
Arg(std::string name);
|
37
37
|
|
38
|
+
// Make Arg polymorphic so dynamic_cast works
|
39
|
+
virtual ~Arg() = default;
|
40
|
+
|
38
41
|
//! Set the default value for this Arg
|
39
42
|
/*! Set the default value for this argument.
|
40
43
|
* If this isn't called on this Arg, then this
|
@@ -56,19 +59,30 @@ namespace Rice
|
|
56
59
|
|
57
60
|
//! Tell the receiving object to keep this argument alive
|
58
61
|
//! until the receiving object is freed.
|
59
|
-
Arg& keepAlive();
|
62
|
+
virtual Arg& keepAlive();
|
60
63
|
|
61
64
|
//! Returns if the argument should be kept alive
|
62
65
|
bool isKeepAlive() const;
|
63
66
|
|
64
67
|
//! Specifies if the argument should be treated as a value
|
65
|
-
Arg& setValue();
|
68
|
+
virtual Arg& setValue();
|
66
69
|
|
67
70
|
//! Returns if the argument should be treated as a value
|
68
71
|
bool isValue() const;
|
69
72
|
|
73
|
+
//! Specifies if the argument is opaque and Rice should not convert it from Ruby to C++ or vice versa.
|
74
|
+
//! This is useful for callbacks and user provided data paramameters.
|
75
|
+
virtual Arg& setOpaque();
|
76
|
+
|
77
|
+
//! Returns if the argument should be treated as a value
|
78
|
+
bool isOpaque() const;
|
79
|
+
|
80
|
+
//! Specifies C++ will take ownership of this value and Ruby should not free it
|
81
|
+
virtual Arg& takeOwnership();
|
82
|
+
bool isOwner();
|
83
|
+
|
70
84
|
public:
|
71
|
-
|
85
|
+
std::string name;
|
72
86
|
int32_t position = -1;
|
73
87
|
|
74
88
|
private:
|
@@ -76,9 +90,9 @@ namespace Rice
|
|
76
90
|
std::any defaultValue_;
|
77
91
|
bool isValue_ = false;
|
78
92
|
bool isKeepAlive_ = false;
|
93
|
+
bool isOwner_ = false;
|
94
|
+
bool isOpaque_ = false;
|
79
95
|
};
|
80
96
|
} // Rice
|
81
97
|
|
82
|
-
#include "Arg.ipp"
|
83
|
-
|
84
98
|
#endif // Rice__Arg__hpp_
|
data/rice/Arg.ipp
CHANGED
@@ -47,4 +47,28 @@ namespace Rice
|
|
47
47
|
{
|
48
48
|
return isValue_;
|
49
49
|
}
|
50
|
+
|
51
|
+
inline Arg& Arg::setOpaque()
|
52
|
+
{
|
53
|
+
isOpaque_ = true;
|
54
|
+
return *this;
|
55
|
+
}
|
56
|
+
|
57
|
+
inline bool Arg::isOpaque() const
|
58
|
+
{
|
59
|
+
return isOpaque_;
|
60
|
+
}
|
61
|
+
|
62
|
+
inline Arg& Arg::takeOwnership()
|
63
|
+
{
|
64
|
+
this->isOwner_ = true;
|
65
|
+
return *this;
|
66
|
+
}
|
67
|
+
|
68
|
+
inline bool Arg::isOwner()
|
69
|
+
{
|
70
|
+
return this->isOwner_;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
50
74
|
} // Rice
|
data/rice/Callback.hpp
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#ifndef Rice__Callback__hpp_
|
2
|
+
#define Rice__Callback__hpp_
|
3
|
+
|
4
|
+
namespace Rice
|
5
|
+
{
|
6
|
+
//! Define a callback.
|
7
|
+
/*! When C++ invokes a C style callback, Rice automatically converts the C++ arguments
|
8
|
+
* to Ruby. However, there may be cases where you need to specify how individual arguments
|
9
|
+
* should be handled. For example, callbacks often have a user data parameter which is
|
10
|
+
* defined as a void pointer (void*). In this case, you need to tell Ruby that the parameter
|
11
|
+
* is opaque and should not be convered. For example:
|
12
|
+
*
|
13
|
+
* define_callback<void(*)(void*)>(Arg("user_data").setOpaque());
|
14
|
+
*
|
15
|
+
* \param args a list of Arg instance used to define default parameters (optional)
|
16
|
+
* \return nothing
|
17
|
+
*/
|
18
|
+
template<typename Callback_T, typename...Arg_Ts>
|
19
|
+
void define_callback(const Arg_Ts&...args);
|
20
|
+
}
|
21
|
+
#endif // Rice__Callback__hpp_
|
data/rice/Callback.ipp
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
namespace Rice
|
2
|
+
{
|
3
|
+
template<typename Callback_T, typename...Arg_Ts>
|
4
|
+
void define_callback(const Arg_Ts&...args)
|
5
|
+
{
|
6
|
+
MethodInfo* methodInfo = new MethodInfo(detail::function_traits<Callback_T>::arity, args...);
|
7
|
+
#ifdef HAVE_LIBFFI
|
8
|
+
detail::NativeCallbackFFI<Callback_T>::setMethodInfo(methodInfo);
|
9
|
+
#else
|
10
|
+
detail::NativeCallbackSimple<Callback_T>::setMethodInfo(methodInfo);
|
11
|
+
#endif
|
12
|
+
}
|
13
|
+
}
|
data/rice/Constructor.hpp
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
#ifndef Rice__Constructor__hpp_
|
2
2
|
#define Rice__Constructor__hpp_
|
3
3
|
|
4
|
-
#include "detail/Wrapper.hpp"
|
5
|
-
#include "cpp_api/Object_defn.hpp"
|
6
|
-
|
7
4
|
namespace Rice
|
8
5
|
{
|
9
6
|
//! Define a Type's Constructor and it's arguments.
|
@@ -13,33 +10,13 @@ namespace Rice
|
|
13
10
|
.define_constructor(Constructor<Test>());
|
14
11
|
\endcode
|
15
12
|
*
|
16
|
-
* The first template
|
17
|
-
*
|
18
|
-
* to
|
13
|
+
* The first template argument must be the type being wrapped.
|
14
|
+
* Additional arguments must be the types of the parameters sent
|
15
|
+
* to the constructor.
|
19
16
|
*
|
20
17
|
* For more information, see Rice::Data_Type::define_constructor.
|
21
18
|
*/
|
22
19
|
template<typename T, typename...Arg_Ts>
|
23
|
-
class Constructor
|
24
|
-
{
|
25
|
-
public:
|
26
|
-
static void construct(VALUE self, Arg_Ts...args)
|
27
|
-
{
|
28
|
-
T* data = new T(args...);
|
29
|
-
detail::replace<T>(self, Data_Type<T>::ruby_data_type(), data, true);
|
30
|
-
}
|
31
|
-
};
|
32
|
-
|
33
|
-
//! Special-case Constructor used when defining Directors.
|
34
|
-
template<typename T, typename...Arg_Ts>
|
35
|
-
class Constructor<T, Object, Arg_Ts...>
|
36
|
-
{
|
37
|
-
public:
|
38
|
-
static void construct(Object self, Arg_Ts...args)
|
39
|
-
{
|
40
|
-
T* data = new T(self, args...);
|
41
|
-
detail::replace<T>(self.value(), Data_Type<T>::ruby_data_type(), data, true);
|
42
|
-
}
|
43
|
-
};
|
20
|
+
class Constructor;
|
44
21
|
}
|
45
22
|
#endif // Rice__Constructor__hpp_
|
@@ -0,0 +1,79 @@
|
|
1
|
+
namespace Rice
|
2
|
+
{
|
3
|
+
template<typename T, typename...Arg_Ts>
|
4
|
+
class Constructor
|
5
|
+
{
|
6
|
+
public:
|
7
|
+
static constexpr std::size_t arity = sizeof...(Arg_Ts);
|
8
|
+
|
9
|
+
static constexpr bool isCopyConstructor()
|
10
|
+
{
|
11
|
+
if constexpr (arity == 1)
|
12
|
+
{
|
13
|
+
using Arg_Types = std::tuple<Arg_Ts...>;
|
14
|
+
using First_Arg_T = std::tuple_element_t<0, Arg_Types>;
|
15
|
+
return (arity == 1 &&
|
16
|
+
std::is_lvalue_reference_v<First_Arg_T> &&
|
17
|
+
std::is_same_v<T, detail::intrinsic_type<First_Arg_T>>);
|
18
|
+
}
|
19
|
+
else
|
20
|
+
{
|
21
|
+
return false;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
static constexpr bool isMoveConstructor()
|
26
|
+
{
|
27
|
+
if constexpr (arity == 1)
|
28
|
+
{
|
29
|
+
using Arg_Types = std::tuple<Arg_Ts...>;
|
30
|
+
using First_Arg_T = std::tuple_element_t<0, Arg_Types>;
|
31
|
+
return (arity == 1 &&
|
32
|
+
std::is_rvalue_reference_v<First_Arg_T> &&
|
33
|
+
std::is_same_v<T, detail::intrinsic_type<First_Arg_T>>);
|
34
|
+
}
|
35
|
+
else
|
36
|
+
{
|
37
|
+
return false;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
static void initialize(VALUE self, Arg_Ts...args)
|
42
|
+
{
|
43
|
+
// Call C++ constructor
|
44
|
+
T* data = new T(args...);
|
45
|
+
detail::replace<T>(self, Data_Type<T>::ruby_data_type(), data, true);
|
46
|
+
}
|
47
|
+
|
48
|
+
static void initialize_copy(VALUE self, const T& other)
|
49
|
+
{
|
50
|
+
// Call C++ copy constructor
|
51
|
+
T* data = new T(other);
|
52
|
+
detail::replace<T>(self, Data_Type<T>::ruby_data_type(), data, true);
|
53
|
+
}
|
54
|
+
|
55
|
+
};
|
56
|
+
|
57
|
+
//! Special-case Constructor used when defining Directors.
|
58
|
+
template<typename T, typename...Arg_Ts>
|
59
|
+
class Constructor<T, Object, Arg_Ts...>
|
60
|
+
{
|
61
|
+
public:
|
62
|
+
static constexpr bool isCopyConstructor()
|
63
|
+
{
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
|
67
|
+
static constexpr bool isMoveConstructor()
|
68
|
+
{
|
69
|
+
return false;
|
70
|
+
}
|
71
|
+
|
72
|
+
static void initialize(Object self, Arg_Ts...args)
|
73
|
+
{
|
74
|
+
// Call C++ constructor
|
75
|
+
T* data = new T(self, args...);
|
76
|
+
detail::replace<T>(self.value(), Data_Type<T>::ruby_data_type(), data, true);
|
77
|
+
}
|
78
|
+
};
|
79
|
+
}
|
data/rice/Data_Object.hpp
CHANGED
@@ -1,8 +1,79 @@
|
|
1
1
|
#ifndef Rice__Data_Object__hpp_
|
2
2
|
#define Rice__Data_Object__hpp_
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
/*! \file
|
5
|
+
* \brief Provides a helper class for wrapping and unwrapping C++
|
6
|
+
* objects as Ruby objects.
|
7
|
+
*/
|
6
8
|
|
7
|
-
|
9
|
+
namespace Rice
|
10
|
+
{
|
11
|
+
//! A smartpointer-like wrapper for Ruby data objects.
|
12
|
+
/*! A data object is a ruby object of type T_DATA, which is usually
|
13
|
+
* created by using the Data_Wrap_Struct or Data_Make_Struct macro.
|
14
|
+
* This class wraps creation of the data structure, providing a
|
15
|
+
* type-safe object-oriented interface to the underlying C interface.
|
16
|
+
* This class works in conjunction with the Data_Type class to ensure
|
17
|
+
* type safety.
|
18
|
+
*
|
19
|
+
* Example:
|
20
|
+
* \code
|
21
|
+
* class Foo { };
|
22
|
+
* ...
|
23
|
+
* Data_Type<Foo> rb_cFoo = define_class("Foo");
|
24
|
+
* ...
|
25
|
+
* // Wrap:
|
26
|
+
* Data_Object<Foo> foo1(new Foo);
|
27
|
+
*
|
28
|
+
* // Get value to return:
|
29
|
+
* VALUE v = foo1.value()
|
30
|
+
*
|
31
|
+
* // Unwrap:
|
32
|
+
* Data_Object<Foo> foo2(v, rb_cFoo);
|
33
|
+
* \endcode
|
34
|
+
*/
|
35
|
+
template<typename T>
|
36
|
+
class Data_Object : public Object
|
37
|
+
{
|
38
|
+
static_assert(!std::is_pointer_v<T>);
|
39
|
+
static_assert(!std::is_reference_v<T>);
|
40
|
+
static_assert(!std::is_const_v<T>);
|
41
|
+
static_assert(!std::is_volatile_v<T>);
|
42
|
+
static_assert(!std::is_void_v<T>);
|
43
|
+
|
44
|
+
public:
|
45
|
+
static T* from_ruby(VALUE value, bool takeOwnership = false);
|
46
|
+
|
47
|
+
public:
|
48
|
+
//! Wrap a C++ object.
|
49
|
+
/*! This constructor is analogous to calling Data_Wrap_Struct. Be
|
50
|
+
* careful not to call this function more than once for the same
|
51
|
+
* pointer (in general, it should only be called for newly
|
52
|
+
* constructed objects that need to be managed by Ruby's garbage
|
53
|
+
* collector).
|
54
|
+
* \param obj the object to wrap.
|
55
|
+
* \param isOwner Should the Data_Object take ownership of the object?
|
56
|
+
* \param klass the Ruby class to use for the newly created Ruby
|
57
|
+
* object.
|
58
|
+
*/
|
59
|
+
Data_Object(T* obj, bool isOwner = false, Class klass = Data_Type<T>::klass());
|
60
|
+
Data_Object(T& obj, bool isOwner = false, Class klass = Data_Type<T>::klass());
|
61
|
+
Data_Object(const T& obj, bool isOwner = false, Class klass = Data_Type<T>::klass());
|
62
|
+
|
63
|
+
//! Unwrap a Ruby object.
|
64
|
+
/*! This constructor is analogous to calling Data_Get_Struct. Uses
|
65
|
+
* Data_Type<T>::klass as the class of the object.
|
66
|
+
* \param value the Ruby object to unwrap.
|
67
|
+
*/
|
68
|
+
Data_Object(Object value);
|
8
69
|
|
70
|
+
T& operator*() const; //!< Return a reference to obj_
|
71
|
+
T* operator->() const; //!< Return a pointer to obj_
|
72
|
+
T* get() const; //!< Return a pointer to obj_
|
73
|
+
|
74
|
+
private:
|
75
|
+
static void check_ruby_type(VALUE value);
|
76
|
+
};
|
77
|
+
} // namespace Rice
|
78
|
+
|
79
|
+
#endif // Rice__Data_Object__hpp_
|