rice 4.3.3 → 4.6.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 +86 -26
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/README.md +7 -2
- data/Rakefile +12 -5
- data/include/rice/rice.hpp +9522 -4426
- data/include/rice/stl.hpp +2831 -1198
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +40 -94
- data/lib/rice/version.rb +3 -0
- data/lib/rice.rb +1 -0
- data/lib/rubygems/builder.rb +11 -0
- data/lib/rubygems/cmake_builder.rb +113 -0
- data/lib/rubygems_plugin.rb +9 -0
- data/rice/Address_Registration_Guard.hpp +72 -3
- data/rice/Arg.hpp +26 -6
- data/rice/Arg.ipp +35 -2
- data/rice/Buffer.hpp +123 -0
- data/rice/Buffer.ipp +599 -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 +73 -3
- data/rice/Data_Object.ipp +388 -96
- data/rice/Data_Type.hpp +214 -3
- data/rice/Data_Type.ipp +144 -67
- data/rice/Director.hpp +0 -2
- data/rice/Enum.hpp +4 -7
- data/rice/Enum.ipp +102 -55
- data/rice/Exception.hpp +62 -2
- data/rice/Exception.ipp +7 -12
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/JumpException.hpp +44 -0
- data/rice/JumpException.ipp +48 -0
- data/rice/MemoryView.hpp +11 -0
- data/rice/MemoryView.ipp +3 -0
- data/rice/Return.hpp +7 -27
- data/rice/Return.ipp +13 -13
- data/rice/cpp_api/Array.hpp +209 -0
- data/rice/cpp_api/Array.ipp +304 -0
- data/rice/cpp_api/Builtin_Object.hpp +31 -0
- data/rice/cpp_api/Builtin_Object.ipp +37 -0
- data/rice/cpp_api/Class.hpp +70 -0
- data/rice/cpp_api/Class.ipp +97 -0
- data/rice/cpp_api/Encoding.hpp +32 -0
- data/rice/cpp_api/Encoding.ipp +59 -0
- data/rice/cpp_api/Hash.hpp +194 -0
- data/rice/cpp_api/Hash.ipp +257 -0
- data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
- data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
- data/rice/cpp_api/Module.hpp +72 -0
- data/rice/cpp_api/Module.ipp +101 -0
- data/rice/cpp_api/Object.hpp +272 -0
- data/rice/cpp_api/Object.ipp +235 -0
- data/rice/cpp_api/String.hpp +74 -0
- data/rice/cpp_api/String.ipp +120 -0
- data/rice/cpp_api/Struct.hpp +113 -0
- data/rice/cpp_api/Struct.ipp +92 -0
- data/rice/cpp_api/Symbol.hpp +46 -0
- data/rice/cpp_api/Symbol.ipp +93 -0
- data/rice/cpp_api/shared_methods.hpp +134 -0
- 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 +12 -10
- data/rice/detail/MethodInfo.ipp +26 -21
- data/rice/detail/Native.hpp +33 -0
- data/rice/detail/Native.ipp +157 -0
- data/rice/detail/NativeAttributeGet.hpp +52 -0
- data/rice/detail/NativeAttributeGet.ipp +57 -0
- data/rice/detail/NativeAttributeSet.hpp +44 -0
- data/rice/detail/NativeAttributeSet.ipp +88 -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 +33 -23
- data/rice/detail/NativeFunction.ipp +309 -70
- data/rice/detail/NativeIterator.hpp +9 -11
- data/rice/detail/NativeIterator.ipp +33 -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 +16 -0
- data/rice/detail/RubyType.ipp +232 -0
- data/rice/detail/Type.hpp +7 -6
- data/rice/detail/Type.ipp +192 -45
- data/rice/detail/TypeRegistry.hpp +15 -7
- data/rice/detail/TypeRegistry.ipp +105 -12
- data/rice/detail/Wrapper.hpp +68 -32
- data/rice/detail/Wrapper.ipp +121 -109
- data/rice/detail/cpp_protect.hpp +5 -6
- data/rice/detail/default_allocation_func.ipp +0 -2
- data/rice/detail/from_ruby.hpp +38 -3
- data/rice/detail/from_ruby.ipp +1321 -492
- data/rice/detail/ruby.hpp +18 -0
- data/rice/detail/to_ruby.hpp +41 -3
- data/rice/detail/to_ruby.ipp +1424 -194
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +116 -26
- data/rice/ruby_mark.hpp +4 -3
- data/rice/stl/complex.hpp +6 -0
- data/rice/stl/complex.ipp +93 -0
- data/rice/stl/exception.hpp +11 -0
- data/rice/stl/exception.ipp +29 -0
- data/rice/stl/exception_ptr.hpp +6 -0
- data/rice/stl/exception_ptr.ipp +27 -0
- data/rice/stl/map.hpp +12 -0
- data/rice/stl/map.ipp +469 -0
- data/rice/stl/monostate.hpp +6 -0
- data/rice/stl/monostate.ipp +80 -0
- data/rice/stl/multimap.hpp +14 -0
- data/rice/stl/multimap.ipp +448 -0
- data/rice/stl/optional.hpp +6 -0
- data/rice/stl/optional.ipp +118 -0
- data/rice/stl/pair.hpp +13 -0
- data/rice/stl/pair.ipp +155 -0
- data/rice/stl/reference_wrapper.hpp +6 -0
- data/rice/stl/reference_wrapper.ipp +41 -0
- data/rice/stl/set.hpp +12 -0
- data/rice/stl/set.ipp +495 -0
- data/rice/stl/shared_ptr.hpp +28 -0
- data/rice/stl/shared_ptr.ipp +224 -0
- data/rice/stl/string.hpp +6 -0
- data/rice/stl/string.ipp +158 -0
- data/rice/stl/string_view.hpp +6 -0
- data/rice/stl/string_view.ipp +65 -0
- data/rice/stl/tuple.hpp +6 -0
- data/rice/stl/tuple.ipp +128 -0
- data/rice/stl/type_index.hpp +6 -0
- data/rice/stl/type_index.ipp +30 -0
- data/rice/stl/type_info.hpp +6 -0
- data/rice/stl/type_info.ipp +29 -0
- data/rice/stl/unique_ptr.hpp +22 -0
- data/rice/stl/unique_ptr.ipp +139 -0
- data/rice/stl/unordered_map.hpp +12 -0
- data/rice/stl/unordered_map.ipp +469 -0
- data/rice/stl/variant.hpp +6 -0
- data/rice/stl/variant.ipp +242 -0
- data/rice/stl/vector.hpp +12 -0
- data/rice/stl/vector.ipp +590 -0
- data/rice/stl.hpp +11 -3
- data/rice/traits/attribute_traits.hpp +26 -0
- data/rice/traits/function_traits.hpp +95 -0
- data/rice/traits/method_traits.hpp +47 -0
- data/rice/traits/rice_traits.hpp +160 -0
- data/rice.gemspec +85 -0
- data/test/embed_ruby.cpp +7 -1
- data/test/extconf.rb +2 -0
- data/test/test_Address_Registration_Guard.cpp +5 -0
- data/test/test_Array.cpp +18 -4
- data/test/test_Attribute.cpp +136 -21
- data/test/test_Buffer.cpp +285 -0
- data/test/test_Builtin_Object.cpp +5 -0
- data/test/test_Callback.cpp +230 -0
- data/test/test_Class.cpp +5 -31
- data/test/test_Constructor.cpp +69 -6
- data/test/test_Data_Object.cpp +97 -38
- data/test/test_Data_Type.cpp +470 -65
- data/test/test_Director.cpp +17 -8
- data/test/test_Enum.cpp +155 -40
- data/test/test_Exception.cpp +235 -0
- data/test/test_File.cpp +70 -0
- data/test/test_From_Ruby.cpp +609 -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 +6 -1
- data/test/test_Jump_Exception.cpp +23 -0
- data/test/test_Keep_Alive.cpp +13 -19
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
- data/test/test_Memory_Management.cpp +5 -0
- data/test/test_Module.cpp +128 -67
- data/test/test_Native_Registry.cpp +2 -34
- data/test/test_Object.cpp +5 -0
- data/test/test_Overloads.cpp +806 -0
- data/test/test_Ownership.cpp +160 -54
- data/test/test_Proc.cpp +44 -0
- data/test/test_Self.cpp +9 -4
- data/test/test_Stl_Exception.cpp +109 -0
- data/test/test_Stl_Map.cpp +54 -42
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Optional.cpp +5 -0
- data/test/test_Stl_Pair.cpp +14 -9
- data/test/test_Stl_Reference_Wrapper.cpp +9 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/test_Stl_SharedPtr.cpp +458 -0
- data/test/test_Stl_String.cpp +5 -0
- data/test/test_Stl_String_View.cpp +5 -0
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +147 -0
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +43 -38
- data/test/test_Stl_Variant.cpp +217 -84
- data/test/test_Stl_Vector.cpp +306 -58
- 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 +524 -0
- data/test/test_Tracking.cpp +1 -0
- data/test/test_Type.cpp +171 -0
- data/test/test_global_functions.cpp +67 -7
- data/test/unittest.cpp +8 -0
- metadata +127 -26
- 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/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_Stl_SmartPointer.cpp +0 -283
- data/test/test_To_From_Ruby.cpp +0 -399
@@ -0,0 +1,72 @@
|
|
1
|
+
#ifndef Rice__Module__hpp_
|
2
|
+
#define Rice__Module__hpp_
|
3
|
+
|
4
|
+
namespace Rice
|
5
|
+
{
|
6
|
+
template <typename T>
|
7
|
+
void validateType();
|
8
|
+
|
9
|
+
//! A helper for defining a Module and its methods.
|
10
|
+
/*! This class provides a C++-style interface to ruby's Module class and
|
11
|
+
* for defining methods on that module.
|
12
|
+
*
|
13
|
+
* Many of the methods are defined in Module_impl.hpp so that they can
|
14
|
+
* return a reference to the most derived type.
|
15
|
+
*/
|
16
|
+
// TODO: we can't inherit from Builtin_Object, because Class needs
|
17
|
+
// type T_CLASS and Module needs type T_MODULE
|
18
|
+
class Module : public Object
|
19
|
+
{
|
20
|
+
public:
|
21
|
+
//! Default construct a Module and initialize it to rb_cObject.
|
22
|
+
Module();
|
23
|
+
|
24
|
+
//! Construct a Module from an existing Module object.
|
25
|
+
Module(VALUE v);
|
26
|
+
|
27
|
+
//! Construct a Module from an string that references a Module
|
28
|
+
Module(std::string name, Object under = rb_cObject);
|
29
|
+
|
30
|
+
//! Return the name of the module.
|
31
|
+
String name() const;
|
32
|
+
|
33
|
+
//! Return an array containing the Module's ancestors.
|
34
|
+
/*! You will need to include Array.hpp to use this function.
|
35
|
+
*/
|
36
|
+
Array ancestors() const;
|
37
|
+
|
38
|
+
//! Return the module's singleton class.
|
39
|
+
/*! You will need to include Class.hpp to use this function.
|
40
|
+
*/
|
41
|
+
Class singleton_class() const;
|
42
|
+
|
43
|
+
//! Evaluate the given string in the context of the module.
|
44
|
+
/*! This is equivalant to calling obj.module_eval(s) from inside the
|
45
|
+
* interpreter.
|
46
|
+
* \return the result of the expression.
|
47
|
+
*/
|
48
|
+
Object module_eval(String const& s);
|
49
|
+
|
50
|
+
#include "shared_methods.hpp"
|
51
|
+
protected:
|
52
|
+
template<bool IsMethod, typename Function_T>
|
53
|
+
void wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo);
|
54
|
+
};
|
55
|
+
|
56
|
+
//! Define a new module in the namespace given by module.
|
57
|
+
/*! \param module the module in which to define the new module.
|
58
|
+
* \param name the name of the new module.
|
59
|
+
*/
|
60
|
+
Module define_module_under(Object module, char const * name);
|
61
|
+
|
62
|
+
//! Define a new module in the default namespace.
|
63
|
+
/*! \param name the name of the new module.
|
64
|
+
*/
|
65
|
+
Module define_module(char const * name);
|
66
|
+
|
67
|
+
//! Create a new anonymous module.
|
68
|
+
/*! \return the new module.
|
69
|
+
*/
|
70
|
+
Module anonymous_module();
|
71
|
+
}
|
72
|
+
#endif // Rice__Module__hpp_
|
@@ -0,0 +1,101 @@
|
|
1
|
+
|
2
|
+
namespace Rice
|
3
|
+
{
|
4
|
+
inline Module::Module() : Object(rb_cObject)
|
5
|
+
{
|
6
|
+
}
|
7
|
+
|
8
|
+
inline Module::Module(VALUE value) : Object(value)
|
9
|
+
{
|
10
|
+
if (::rb_type(value) != T_CLASS && ::rb_type(value) != T_MODULE)
|
11
|
+
{
|
12
|
+
throw Exception(
|
13
|
+
rb_eTypeError,
|
14
|
+
"Expected a Module but got a %s",
|
15
|
+
detail::protect(rb_obj_classname, value)); // TODO: might raise an exception
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
//! Construct a Module from an string that references a Module
|
20
|
+
inline Module::Module(std::string name, Object under)
|
21
|
+
{
|
22
|
+
VALUE result = under.const_get(name);
|
23
|
+
|
24
|
+
if (::rb_type(result) != T_MODULE)
|
25
|
+
{
|
26
|
+
throw Exception(
|
27
|
+
rb_eTypeError,
|
28
|
+
"Expected a Module but got a %s",
|
29
|
+
detail::protect(rb_obj_classname, result)); // TODO: might raise an exception
|
30
|
+
}
|
31
|
+
|
32
|
+
this->set_value(result);
|
33
|
+
}
|
34
|
+
|
35
|
+
template<bool IsMethod, typename Function_T>
|
36
|
+
inline void Module::wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo)
|
37
|
+
{
|
38
|
+
// Make sure the return type and arguments have been previously seen by Rice
|
39
|
+
using traits = detail::method_traits<Function_T, IsMethod>;
|
40
|
+
detail::verifyType<typename traits::Return_T>();
|
41
|
+
detail::verifyTypes<typename traits::Arg_Ts>();
|
42
|
+
|
43
|
+
// Define a NativeFunction to bridge Ruby to C++
|
44
|
+
detail::NativeFunction<VALUE, Function_T, IsMethod>::define(klass, name, std::forward<Function_T>(function), methodInfo);
|
45
|
+
}
|
46
|
+
|
47
|
+
inline Module define_module_under(Object module, char const* name)
|
48
|
+
{
|
49
|
+
return detail::protect(rb_define_module_under, module.value(), name);
|
50
|
+
}
|
51
|
+
|
52
|
+
inline Module define_module(char const* name)
|
53
|
+
{
|
54
|
+
return detail::protect(rb_define_module, name);
|
55
|
+
}
|
56
|
+
|
57
|
+
inline Module anonymous_module()
|
58
|
+
{
|
59
|
+
VALUE klass = detail::protect(rb_module_new);
|
60
|
+
VALUE singleton = detail::protect(rb_singleton_class, klass);
|
61
|
+
|
62
|
+
// Ruby will reuse addresses previously assigned to other modules
|
63
|
+
// that have subsequently been garbage collected
|
64
|
+
detail::Registries::instance.natives.reset(klass);
|
65
|
+
detail::Registries::instance.natives.reset(singleton);
|
66
|
+
|
67
|
+
return klass;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
namespace Rice::detail
|
72
|
+
{
|
73
|
+
template<>
|
74
|
+
struct Type<Module>
|
75
|
+
{
|
76
|
+
static bool verify()
|
77
|
+
{
|
78
|
+
return true;
|
79
|
+
}
|
80
|
+
};
|
81
|
+
|
82
|
+
template<>
|
83
|
+
class To_Ruby<Module>
|
84
|
+
{
|
85
|
+
public:
|
86
|
+
VALUE convert(Module const& x)
|
87
|
+
{
|
88
|
+
return x.value();
|
89
|
+
}
|
90
|
+
};
|
91
|
+
|
92
|
+
template<>
|
93
|
+
class From_Ruby<Module>
|
94
|
+
{
|
95
|
+
public:
|
96
|
+
Module convert(VALUE value)
|
97
|
+
{
|
98
|
+
return Module(value);
|
99
|
+
}
|
100
|
+
};
|
101
|
+
}
|
@@ -0,0 +1,272 @@
|
|
1
|
+
#ifndef Rice__Object__hpp_
|
2
|
+
#define Rice__Object__hpp_
|
3
|
+
|
4
|
+
/*! \file Object.hpp
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <iosfwd>
|
8
|
+
|
9
|
+
namespace Rice
|
10
|
+
{
|
11
|
+
class Class;
|
12
|
+
class String;
|
13
|
+
class Array;
|
14
|
+
|
15
|
+
//! The base class for all Objects
|
16
|
+
/*! Perhaps the name "Object" is a misnomer, because this class really
|
17
|
+
* holds an object reference, not an object.
|
18
|
+
*/
|
19
|
+
class Object
|
20
|
+
{
|
21
|
+
public:
|
22
|
+
//! Encapsulate an existing ruby object.
|
23
|
+
Object(VALUE value = Qnil) : value_(value) {}
|
24
|
+
|
25
|
+
//! Destructor
|
26
|
+
virtual ~Object();
|
27
|
+
|
28
|
+
// Enable copying
|
29
|
+
Object(const Object& other) = default;
|
30
|
+
Object& operator=(const Object& other) = default;
|
31
|
+
|
32
|
+
// Enable moving
|
33
|
+
Object(Object&& other);
|
34
|
+
Object& operator=(Object&& other);
|
35
|
+
|
36
|
+
//! Returns false if the object is nil or false; returns true
|
37
|
+
//! otherwise.
|
38
|
+
// Having this conversion also prevents accidental conversion to
|
39
|
+
// undesired integral types (e.g. long or int) by making the
|
40
|
+
// conversion ambiguous.
|
41
|
+
bool test() const { return RTEST(value_); }
|
42
|
+
|
43
|
+
//! Returns false if the object is nil or false; returns true
|
44
|
+
//! otherwise.
|
45
|
+
operator bool() const { return test(); }
|
46
|
+
|
47
|
+
//! Returns true if the object is nil, false otherwise.
|
48
|
+
bool is_nil() const { return NIL_P(value_); }
|
49
|
+
|
50
|
+
//! Implicit conversion to VALUE.
|
51
|
+
operator VALUE() const { return value_; }
|
52
|
+
|
53
|
+
//! Explicitly get the encapsulated VALUE.
|
54
|
+
// Returns a const ref so that Address_Registration_Guard can access
|
55
|
+
// the address where the VALUE is stored
|
56
|
+
VALUE const volatile& value() const { return value_; }
|
57
|
+
|
58
|
+
//! Get the class of an object.
|
59
|
+
/*! \return the object's Class.
|
60
|
+
*/
|
61
|
+
Class class_of() const;
|
62
|
+
|
63
|
+
//! Compare this object to another object.
|
64
|
+
/*! Gets the result of self <=> other and returns the result. The
|
65
|
+
* result will be less than zero if self < other, greater than zero
|
66
|
+
* if self > other, and equal to zero if self == other.
|
67
|
+
*/
|
68
|
+
int compare(Object const& other) const;
|
69
|
+
|
70
|
+
//! Return a string representation of an object.
|
71
|
+
/*! \return the result of calling to_s on the object. A String is not
|
72
|
+
* returned, because it is not possible to return an instance of a
|
73
|
+
* derived class.
|
74
|
+
*/
|
75
|
+
String to_s() const;
|
76
|
+
|
77
|
+
//! Return the name of an object's class.
|
78
|
+
String class_name() const;
|
79
|
+
|
80
|
+
//! Inspect the object.
|
81
|
+
/*! \return the result of calling inspect on the object. A String is
|
82
|
+
* not returned, because it is not possible to return an instance of
|
83
|
+
* a derived class.
|
84
|
+
*/
|
85
|
+
String inspect() const;
|
86
|
+
|
87
|
+
//! Freeze the object.
|
88
|
+
void freeze();
|
89
|
+
|
90
|
+
//! Determine if the object is frozen.
|
91
|
+
/*! \return true if the object is frozen, false otherwise.
|
92
|
+
*/
|
93
|
+
bool is_frozen() const;
|
94
|
+
|
95
|
+
//! Evaluate the given string in the context of the object.
|
96
|
+
/*! This is equivalant to calling obj.instance_eval(s) from inside the
|
97
|
+
* interpreter.
|
98
|
+
* \return the result of the expression.
|
99
|
+
*/
|
100
|
+
Object instance_eval(String const& s);
|
101
|
+
|
102
|
+
//! Return the type of the underlying C object.
|
103
|
+
/*! This is equivalent to calling rb_type(obj).
|
104
|
+
* \return the type of the underlying C object (e.g. T_DATA, T_ARRAY,
|
105
|
+
* etc.).
|
106
|
+
*/
|
107
|
+
int rb_type() const;
|
108
|
+
|
109
|
+
//! Return the object's id
|
110
|
+
VALUE object_id() const;
|
111
|
+
|
112
|
+
//! Determine whether the object is an instance of a class/module.
|
113
|
+
/*! \param klass a class or module.
|
114
|
+
* \return true if the object is an instance of the given
|
115
|
+
* class/module or one of its descendants.
|
116
|
+
*/
|
117
|
+
bool is_a(Object klass) const;
|
118
|
+
|
119
|
+
//! Determine if the objects responds to a method.
|
120
|
+
/*! \param id the name of the method
|
121
|
+
* \return true if the objects responds to the method, false
|
122
|
+
* otherwise.
|
123
|
+
*/
|
124
|
+
bool respond_to(Identifier id) const;
|
125
|
+
|
126
|
+
//! Determine whether class is the object's class.
|
127
|
+
/*! \param klass a class.
|
128
|
+
* \return true if the object is an instance of the given class.
|
129
|
+
*/
|
130
|
+
bool is_instance_of(Object klass) const;
|
131
|
+
|
132
|
+
//! Determine whether the Ruby VALUEs wrapped by this
|
133
|
+
//! object are the same object. Maps to Object::equal?
|
134
|
+
/*! \param other a Object.
|
135
|
+
*/
|
136
|
+
bool is_equal(const Object& other) const;
|
137
|
+
|
138
|
+
//! Determine whether the Ruby VALUEs wrapped by this
|
139
|
+
//! object are equivalent. Maps to Object::eql?
|
140
|
+
/*! \param other a Object.
|
141
|
+
*/
|
142
|
+
bool is_eql(const Object& other) const;
|
143
|
+
|
144
|
+
//! Set an instance variable.
|
145
|
+
/*! \param name the name of the instance variable to set (including
|
146
|
+
* the leading @ sign)
|
147
|
+
* \param value the value of the variable, which will be converted to
|
148
|
+
* a Ruby type if necessary.
|
149
|
+
*/
|
150
|
+
template<typename T>
|
151
|
+
void iv_set(Identifier name, T const& value);
|
152
|
+
|
153
|
+
//! Get the value of an instance variable.
|
154
|
+
/*! \param name the name of the instance variable to get
|
155
|
+
* \return the value of the instance variable
|
156
|
+
*/
|
157
|
+
Object iv_get(Identifier name) const;
|
158
|
+
|
159
|
+
//! Get the value of an instance variable, but don't warn if it is
|
160
|
+
//unset.
|
161
|
+
/*! \param name the name of the instance variable to get
|
162
|
+
* \return the value of the instance variable
|
163
|
+
*/
|
164
|
+
Object attr_get(Identifier name) const;
|
165
|
+
|
166
|
+
//! Call the Ruby method specified by 'id' on object 'obj'.
|
167
|
+
/*! Pass in arguments (arg1, arg2, ...). The arguments will be converted to
|
168
|
+
* Ruby objects with to_ruby<>. To call methods expecting keyword arguments,
|
169
|
+
* use call_kw.
|
170
|
+
*
|
171
|
+
* E.g.:
|
172
|
+
* \code
|
173
|
+
* Rice::Object obj = x.call("foo", "one", 2);
|
174
|
+
* \endcode
|
175
|
+
*
|
176
|
+
* If a return type is specified, the return value will automatically be
|
177
|
+
* converted to that type as long as 'from_ruby' exists for that type.
|
178
|
+
*
|
179
|
+
* E.g.:
|
180
|
+
* \code
|
181
|
+
* float ret = x.call<float>("foo", z, 42);
|
182
|
+
* \endcode
|
183
|
+
*/
|
184
|
+
template<typename ...Arg_Ts>
|
185
|
+
Object call(Identifier id, Arg_Ts... args) const;
|
186
|
+
|
187
|
+
//! Call the Ruby method specified by 'id' on object 'obj'.
|
188
|
+
/*! Pass in arguments (arg1, arg2, ...). The arguments will be converted to
|
189
|
+
* Ruby objects with to_ruby<>. The final argument must be a Hash and will be treated
|
190
|
+
* as keyword arguments to the function.
|
191
|
+
*
|
192
|
+
* E.g.:
|
193
|
+
* \code
|
194
|
+
* Rice::Hash kw;
|
195
|
+
* kw[":argument"] = String("one")
|
196
|
+
* Rice::Object obj = x.call_kw("foo", kw);
|
197
|
+
* \endcode
|
198
|
+
*
|
199
|
+
* If a return type is specified, the return value will automatically be
|
200
|
+
* converted to that type as long as 'from_ruby' exists for that type.
|
201
|
+
*
|
202
|
+
* E.g.:
|
203
|
+
* \code
|
204
|
+
* float ret = x.call_kw<float>("foo", kw);
|
205
|
+
* \endcode
|
206
|
+
*/
|
207
|
+
template<typename ...Arg_Ts>
|
208
|
+
Object call_kw(Identifier id, Arg_Ts... args) const;
|
209
|
+
|
210
|
+
//! Vectorized call.
|
211
|
+
/*! Calls the method identified by id with the list of arguments
|
212
|
+
* identified by args.
|
213
|
+
* \param id the name of the method to call
|
214
|
+
* \param args the arguments to the method
|
215
|
+
* \return the return value of the method call
|
216
|
+
*/
|
217
|
+
Object vcall(Identifier id, Array args);
|
218
|
+
|
219
|
+
//! Get a constant.
|
220
|
+
/*! \param name the name of the constant to get.
|
221
|
+
* \return the value of the constant.
|
222
|
+
*/
|
223
|
+
Object const_get(Identifier name) const;
|
224
|
+
|
225
|
+
//! Determine whether a constant is defined.
|
226
|
+
/*! \param name the name of the constant to check.
|
227
|
+
* \return true if the constant is defined in this module or false
|
228
|
+
* otherwise.
|
229
|
+
*/
|
230
|
+
bool const_defined(Identifier name) const;
|
231
|
+
|
232
|
+
//! Set a constant.
|
233
|
+
/*! \param name the name of the constant to set.
|
234
|
+
* \param value the value of the constant.
|
235
|
+
* \return *this
|
236
|
+
*/
|
237
|
+
inline Object const_set(Identifier name, Object value);
|
238
|
+
|
239
|
+
//! Set a constant if it not already set.
|
240
|
+
/*! \param name the name of the constant to set.
|
241
|
+
* \param value the value of the constant.
|
242
|
+
* \return *this
|
243
|
+
*/
|
244
|
+
inline Object const_set_maybe(Identifier name, Object value);
|
245
|
+
|
246
|
+
//! Remove a constant.
|
247
|
+
/*! \param name the name of the constant to remove.
|
248
|
+
*/
|
249
|
+
void remove_const(Identifier name);
|
250
|
+
|
251
|
+
protected:
|
252
|
+
//! Set the encapsulated value.
|
253
|
+
void set_value(VALUE v);
|
254
|
+
|
255
|
+
private:
|
256
|
+
volatile VALUE value_;
|
257
|
+
};
|
258
|
+
|
259
|
+
std::ostream& operator<<(std::ostream& out, Object const& obj);
|
260
|
+
|
261
|
+
bool operator==(Object const& lhs, Object const& rhs);
|
262
|
+
bool operator!=(Object const& lhs, Object const& rhs);
|
263
|
+
bool operator<(Object const& lhs, Object const& rhs);
|
264
|
+
bool operator>(Object const& lhs, Object const& rhs);
|
265
|
+
|
266
|
+
extern Object const Nil;
|
267
|
+
extern Object const True;
|
268
|
+
extern Object const False;
|
269
|
+
extern Object const Undef;
|
270
|
+
} // namespace Rice
|
271
|
+
|
272
|
+
#endif // Rice__Object__hpp_
|
@@ -0,0 +1,235 @@
|
|
1
|
+
namespace Rice
|
2
|
+
{
|
3
|
+
inline const Object Nil(Qnil);
|
4
|
+
inline const Object True(Qtrue);
|
5
|
+
inline const Object False(Qfalse);
|
6
|
+
inline const Object Undef(Qundef);
|
7
|
+
|
8
|
+
// Ruby auto detects VALUEs in the stack, so when an Object gets deleted make sure
|
9
|
+
// to clean up in case it is on the stack
|
10
|
+
inline Object::~Object()
|
11
|
+
{
|
12
|
+
this->value_ = Qnil;
|
13
|
+
}
|
14
|
+
|
15
|
+
// Move constructor
|
16
|
+
inline Object::Object(Object&& other)
|
17
|
+
{
|
18
|
+
this->value_ = other.value_;
|
19
|
+
other.value_ = Qnil;
|
20
|
+
}
|
21
|
+
|
22
|
+
// Move assignment
|
23
|
+
inline Object& Object::operator=(Object&& other)
|
24
|
+
{
|
25
|
+
this->value_ = other.value_;
|
26
|
+
other.value_ = Qnil;
|
27
|
+
return *this;
|
28
|
+
}
|
29
|
+
|
30
|
+
template<typename ...Arg_Ts>
|
31
|
+
inline Object Object::call(Identifier id, Arg_Ts... args) const
|
32
|
+
{
|
33
|
+
/* IMPORTANT - We store VALUEs in an array that is a local variable.
|
34
|
+
That allows the Ruby garbage collector to find them when scanning
|
35
|
+
the stack and thus mark them. If instead we use a vector, then Ruby's GC
|
36
|
+
can't find the VALUEs and may garbage collect them before they are sent
|
37
|
+
to the destination method resulting in a segmentation fault. This is
|
38
|
+
easy to duplicate by setting GC.stress to true and calling a constructor
|
39
|
+
that takes multiple values like a std::pair wrapper. */
|
40
|
+
std::array<VALUE, sizeof...(Arg_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Arg_Ts>>().convert(std::forward<Arg_Ts>(args))... };
|
41
|
+
return detail::protect(rb_funcallv, value(), id.id(), (int)values.size(), (const VALUE*)values.data());
|
42
|
+
}
|
43
|
+
|
44
|
+
template<typename ...Arg_Ts>
|
45
|
+
inline Object Object::call_kw(Identifier id, Arg_Ts... args) const
|
46
|
+
{
|
47
|
+
/* IMPORTANT - See call() above */
|
48
|
+
std::array<VALUE, sizeof...(Arg_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Arg_Ts>>().convert(args)... };
|
49
|
+
return detail::protect(rb_funcallv_kw, value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
|
50
|
+
}
|
51
|
+
|
52
|
+
template<typename T>
|
53
|
+
inline void Object::iv_set(Identifier name, T const& value)
|
54
|
+
{
|
55
|
+
detail::protect(rb_ivar_set, this->value(), name.id(), detail::To_Ruby<T>().convert(value));
|
56
|
+
}
|
57
|
+
|
58
|
+
inline int Object::compare(Object const& other) const
|
59
|
+
{
|
60
|
+
Object result = call("<=>", other);
|
61
|
+
return detail::From_Ruby<int>().convert(result);
|
62
|
+
}
|
63
|
+
|
64
|
+
inline bool Object::is_equal(const Object& other) const
|
65
|
+
{
|
66
|
+
VALUE result = detail::protect(rb_equal, this->value_, other.value_);
|
67
|
+
return RB_TEST(result);
|
68
|
+
}
|
69
|
+
|
70
|
+
inline bool Object::is_eql(const Object& other) const
|
71
|
+
{
|
72
|
+
VALUE result = detail::protect(rb_eql, this->value_, other.value_);
|
73
|
+
return RB_TEST(result);
|
74
|
+
}
|
75
|
+
|
76
|
+
inline void Object::freeze()
|
77
|
+
{
|
78
|
+
detail::protect(rb_obj_freeze, value());
|
79
|
+
}
|
80
|
+
|
81
|
+
inline bool Object::is_frozen() const
|
82
|
+
{
|
83
|
+
return RB_OBJ_FROZEN(value());
|
84
|
+
}
|
85
|
+
|
86
|
+
inline int Object::rb_type() const
|
87
|
+
{
|
88
|
+
return ::rb_type(this->value());
|
89
|
+
}
|
90
|
+
|
91
|
+
inline VALUE Object::object_id() const
|
92
|
+
{
|
93
|
+
return detail::protect(rb_obj_id, this->value());
|
94
|
+
}
|
95
|
+
|
96
|
+
inline bool Object::is_a(Object klass) const
|
97
|
+
{
|
98
|
+
VALUE result = detail::protect(rb_obj_is_kind_of, this->value(), klass.value());
|
99
|
+
return RB_TEST(result);
|
100
|
+
}
|
101
|
+
|
102
|
+
inline bool Object::respond_to(Identifier id) const
|
103
|
+
{
|
104
|
+
return bool(rb_respond_to(this->value(), id.id()));
|
105
|
+
}
|
106
|
+
|
107
|
+
inline bool Object::is_instance_of(Object klass) const
|
108
|
+
{
|
109
|
+
VALUE result = detail::protect(rb_obj_is_instance_of, this->value(), klass.value());
|
110
|
+
return RB_TEST(result);
|
111
|
+
}
|
112
|
+
|
113
|
+
inline Object Object::iv_get(Identifier name) const
|
114
|
+
{
|
115
|
+
return detail::protect(rb_ivar_get, this->value(), name.id());
|
116
|
+
}
|
117
|
+
|
118
|
+
inline Object Object::attr_get(Identifier name) const
|
119
|
+
{
|
120
|
+
return detail::protect(rb_attr_get, this->value(), name.id());
|
121
|
+
}
|
122
|
+
|
123
|
+
inline void Object::set_value(VALUE v)
|
124
|
+
{
|
125
|
+
value_ = v;
|
126
|
+
}
|
127
|
+
|
128
|
+
inline Object Object::const_get(Identifier name) const
|
129
|
+
{
|
130
|
+
return detail::protect(rb_const_get, this->value(), name.id());
|
131
|
+
}
|
132
|
+
|
133
|
+
inline bool Object::const_defined(Identifier name) const
|
134
|
+
{
|
135
|
+
size_t result = detail::protect(rb_const_defined, this->value(), name.id());
|
136
|
+
return bool(result);
|
137
|
+
}
|
138
|
+
|
139
|
+
inline Object Object::const_set(Identifier name, Object value)
|
140
|
+
{
|
141
|
+
detail::protect(rb_const_set, this->value(), name.id(), value.value());
|
142
|
+
return value;
|
143
|
+
}
|
144
|
+
|
145
|
+
inline Object Object::const_set_maybe(Identifier name, Object value)
|
146
|
+
{
|
147
|
+
if (!this->const_defined(name))
|
148
|
+
{
|
149
|
+
this->const_set(name, value);
|
150
|
+
}
|
151
|
+
return value;
|
152
|
+
}
|
153
|
+
|
154
|
+
inline void Object::remove_const(Identifier name)
|
155
|
+
{
|
156
|
+
detail::protect(rb_mod_remove_const, this->value(), name.to_sym());
|
157
|
+
}
|
158
|
+
|
159
|
+
inline bool operator==(Object const& lhs, Object const& rhs)
|
160
|
+
{
|
161
|
+
VALUE result = detail::protect(rb_equal, lhs.value(), rhs.value());
|
162
|
+
return result == Qtrue ? true : false;
|
163
|
+
}
|
164
|
+
|
165
|
+
inline bool operator!=(Object const& lhs, Object const& rhs)
|
166
|
+
{
|
167
|
+
return !(lhs == rhs);
|
168
|
+
}
|
169
|
+
|
170
|
+
inline bool operator<(Object const& lhs, Object const& rhs)
|
171
|
+
{
|
172
|
+
Object result = lhs.call("<", rhs);
|
173
|
+
return result.test();
|
174
|
+
}
|
175
|
+
|
176
|
+
inline bool operator>(Object const& lhs, Object const& rhs)
|
177
|
+
{
|
178
|
+
Object result = lhs.call(">", rhs);
|
179
|
+
return result.test();
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
namespace Rice::detail
|
184
|
+
{
|
185
|
+
template<>
|
186
|
+
struct Type<Object>
|
187
|
+
{
|
188
|
+
static bool verify()
|
189
|
+
{
|
190
|
+
return true;
|
191
|
+
}
|
192
|
+
};
|
193
|
+
|
194
|
+
template<>
|
195
|
+
class To_Ruby<Object>
|
196
|
+
{
|
197
|
+
public:
|
198
|
+
static VALUE convert(Object const& x)
|
199
|
+
{
|
200
|
+
return x.value();
|
201
|
+
}
|
202
|
+
};
|
203
|
+
|
204
|
+
template<>
|
205
|
+
class To_Ruby<Object&>
|
206
|
+
{
|
207
|
+
public:
|
208
|
+
static VALUE convert(Object const& x)
|
209
|
+
{
|
210
|
+
return x.value();
|
211
|
+
}
|
212
|
+
};
|
213
|
+
|
214
|
+
template<>
|
215
|
+
class From_Ruby<Object>
|
216
|
+
{
|
217
|
+
public:
|
218
|
+
Convertible is_convertible(VALUE value)
|
219
|
+
{
|
220
|
+
switch (rb_type(value))
|
221
|
+
{
|
222
|
+
case RUBY_T_OBJECT:
|
223
|
+
return Convertible::Exact;
|
224
|
+
break;
|
225
|
+
default:
|
226
|
+
return Convertible::None;
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
Object convert(VALUE value)
|
231
|
+
{
|
232
|
+
return Object(value);
|
233
|
+
}
|
234
|
+
};
|
235
|
+
}
|