rice 4.3.3 → 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +63 -26
- data/README.md +7 -2
- data/Rakefile +7 -1
- data/include/rice/rice.hpp +7291 -4430
- 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 -15
- data/rice/detail/NativeRegistry.ipp +23 -48
- 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_
|