rice 1.3.2 → 1.4.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.
- data/Doxyfile +1 -1
- data/README +43 -0
- data/Rakefile +1 -1
- data/extconf.rb +3 -1
- data/rice/Data_Type.ipp +53 -3
- data/rice/Data_Type_defn.hpp +20 -5
- data/rice/config.hpp +5 -5
- data/rice/detail/Caster.hpp +40 -0
- data/rice/detail/ruby_version_code.hpp +1 -1
- data/rice/detail/to_ruby.ipp +1 -2
- data/rice/ruby_mark.hpp +1 -1
- data/ruby/lib/mkmf-rice.rb.in +1 -1
- data/ruby/lib/version.rb +1 -1
- data/sample/enum/test.rb +1 -0
- data/test/Makefile.am +2 -0
- data/test/Makefile.in +8 -5
- data/test/test_Constructor.cpp +39 -38
- data/test/test_Data_Type.cpp +227 -0
- data/test/test_Memory_Management.cpp +50 -0
- metadata +10 -5
data/Doxyfile
CHANGED
|
@@ -23,7 +23,7 @@ PROJECT_NAME = Rice
|
|
|
23
23
|
# This could be handy for archiving the generated documentation or
|
|
24
24
|
# if some version control system is used.
|
|
25
25
|
|
|
26
|
-
PROJECT_NUMBER = 1.
|
|
26
|
+
PROJECT_NUMBER = 1.4.0
|
|
27
27
|
|
|
28
28
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
|
29
29
|
# base path where the generated documentation will be put.
|
data/README
CHANGED
|
@@ -695,6 +695,12 @@ can be used as expected:
|
|
|
695
695
|
t.hello("goodnight", "moon")
|
|
696
696
|
\endcode
|
|
697
697
|
|
|
698
|
+
This will also work with Constructors:
|
|
699
|
+
|
|
700
|
+
\code
|
|
701
|
+
.define_constructor(Constructor<SomeClass, int, int>(),
|
|
702
|
+
( Arg("arg1") = 1, Arg("otherArg") = 12 );
|
|
703
|
+
\endcode
|
|
698
704
|
|
|
699
705
|
\section director Director
|
|
700
706
|
|
|
@@ -822,6 +828,43 @@ Rice::Data_Type::define_director, then define methods pointing to the proxy obje
|
|
|
822
828
|
You must use the Rice::Director proxy class in the Constructor line, this allows proper
|
|
823
829
|
object construction / destruction of the types in question.
|
|
824
830
|
|
|
831
|
+
\section implicit_cast Implicit Casting
|
|
832
|
+
|
|
833
|
+
There are times when a library exposes classes that while unrelated are
|
|
834
|
+
built to be interchangeable across the library. One example of this,
|
|
835
|
+
taken from Ogre, are the Degree and Radian classes. When a given method
|
|
836
|
+
takes a Radian, you're free to pass in a Degree, and vice versa.
|
|
837
|
+
|
|
838
|
+
Rice cannot automatically figure out if this kind of functionality is
|
|
839
|
+
possible in a given library but it does have a simple API for defining
|
|
840
|
+
these relationships: Rice::define_implicit_cast<From, To>().
|
|
841
|
+
|
|
842
|
+
\code
|
|
843
|
+
class Degree { ... };
|
|
844
|
+
class Radian { ... };
|
|
845
|
+
|
|
846
|
+
extern "C"
|
|
847
|
+
void Init_implicit() {
|
|
848
|
+
define_class<Degree>()
|
|
849
|
+
...;
|
|
850
|
+
define_class<Radian>()
|
|
851
|
+
...;
|
|
852
|
+
|
|
853
|
+
define_implicit_cast<Degree, Radian>();
|
|
854
|
+
define_implicit_cast<Radian, Degree>();
|
|
855
|
+
}
|
|
856
|
+
\endcode
|
|
857
|
+
|
|
858
|
+
This support is still being fleshed out and has a few requirements for
|
|
859
|
+
proper use:
|
|
860
|
+
|
|
861
|
+
\li The two types must be bound in Rice before defining the cast.
|
|
862
|
+
\li The classes must have constructors that take the other type.
|
|
863
|
+
\li This feature cannot be used with fundamental types yet.
|
|
864
|
+
|
|
865
|
+
To see a full example of this feature, please check out
|
|
866
|
+
test/test_Data_Type.cpp.
|
|
867
|
+
|
|
825
868
|
\section motivation Motivation
|
|
826
869
|
|
|
827
870
|
There are a number of common problems when writing C or C++ extensions
|
data/Rakefile
CHANGED
data/extconf.rb
CHANGED
|
@@ -26,9 +26,11 @@ with_ruby = File.join(Config::CONFIG["bindir"], Config::CONFIG["RUBY_INSTALL_NAM
|
|
|
26
26
|
other_opts = ""
|
|
27
27
|
env = ""
|
|
28
28
|
|
|
29
|
+
arch = Config::CONFIG["arch"].split("-")[0]
|
|
30
|
+
|
|
29
31
|
if RUBY_PLATFORM =~ /darwin10/
|
|
30
32
|
other_opts = "--disable-dependency-tracking"
|
|
31
|
-
env = "ARCHFLAGS='-arch
|
|
33
|
+
env = "ARCHFLAGS='-arch #{arch}'"
|
|
32
34
|
elsif RUBY_PLATFORM =~ /darwin9/
|
|
33
35
|
env = "ARCHFLAGS='-arch #{`uname -p`.chomp}'"
|
|
34
36
|
end
|
data/rice/Data_Type.ipp
CHANGED
|
@@ -121,7 +121,8 @@ template<typename T>
|
|
|
121
121
|
template<typename Constructor_T>
|
|
122
122
|
inline Rice::Data_Type<T> & Rice::Data_Type<T>::
|
|
123
123
|
define_constructor(
|
|
124
|
-
Constructor_T constructor
|
|
124
|
+
Constructor_T /* constructor */,
|
|
125
|
+
Arguments* arguments)
|
|
125
126
|
{
|
|
126
127
|
check_is_bound();
|
|
127
128
|
|
|
@@ -129,11 +130,28 @@ define_constructor(
|
|
|
129
130
|
rb_define_alloc_func(
|
|
130
131
|
static_cast<VALUE>(*this),
|
|
131
132
|
detail::default_allocation_func<T>);
|
|
132
|
-
define_method(
|
|
133
|
+
define_method(
|
|
134
|
+
"initialize",
|
|
135
|
+
&Constructor_T::construct,
|
|
136
|
+
arguments
|
|
137
|
+
);
|
|
133
138
|
|
|
134
139
|
return *this;
|
|
135
140
|
}
|
|
136
141
|
|
|
142
|
+
template<typename T>
|
|
143
|
+
template<typename Constructor_T>
|
|
144
|
+
inline Rice::Data_Type<T> & Rice::Data_Type<T>::
|
|
145
|
+
define_constructor(
|
|
146
|
+
Constructor_T constructor,
|
|
147
|
+
Arg const& arg)
|
|
148
|
+
{
|
|
149
|
+
Arguments* args = new Arguments();
|
|
150
|
+
args->add(arg);
|
|
151
|
+
return define_constructor(constructor, args);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
137
155
|
template<typename T>
|
|
138
156
|
template<typename Director_T>
|
|
139
157
|
inline Rice::Data_Type<T>& Rice::Data_Type<T>::
|
|
@@ -177,7 +195,7 @@ from_ruby(Object x)
|
|
|
177
195
|
|
|
178
196
|
VALUE ancestors = rb_mod_ancestors(klass.value());
|
|
179
197
|
|
|
180
|
-
|
|
198
|
+
long earliest = RARRAY_LEN(ancestors) + 1;
|
|
181
199
|
|
|
182
200
|
int index;
|
|
183
201
|
VALUE indexFound;
|
|
@@ -312,4 +330,36 @@ define_class(
|
|
|
312
330
|
return Data_Type<T>::template bind<Base_T>(c);
|
|
313
331
|
}
|
|
314
332
|
|
|
333
|
+
template<typename From_T, typename To_T>
|
|
334
|
+
inline void
|
|
335
|
+
Rice::define_implicit_cast()
|
|
336
|
+
{
|
|
337
|
+
// As Rice currently expects only one entry into
|
|
338
|
+
// this list for a given klass VALUE, we need to get
|
|
339
|
+
// the current caster for From_T and insert in our
|
|
340
|
+
// new caster as the head of the caster list
|
|
341
|
+
|
|
342
|
+
Class from_class = Data_Type<From_T>::klass().value();
|
|
343
|
+
Class to_class = Data_Type<To_T>::klass().value();
|
|
344
|
+
|
|
345
|
+
detail::Abstract_Caster* from_caster =
|
|
346
|
+
Data_Type<From_T>::caster_.release();
|
|
347
|
+
|
|
348
|
+
detail::Abstract_Caster* new_caster =
|
|
349
|
+
new detail::Implicit_Caster<To_T, From_T>(from_caster, to_class);
|
|
350
|
+
|
|
351
|
+
// Insert our new caster into the list for the from class
|
|
352
|
+
Data_Type_Base::casters().erase(from_class);
|
|
353
|
+
Data_Type_Base::casters().insert(
|
|
354
|
+
std::make_pair(
|
|
355
|
+
from_class,
|
|
356
|
+
new_caster
|
|
357
|
+
)
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
// And make sure the from_class has direct access to the
|
|
361
|
+
// updated caster list
|
|
362
|
+
Data_Type<From_T>::caster_.reset(new_caster);
|
|
363
|
+
}
|
|
364
|
+
|
|
315
365
|
#endif // Rice__Data_Type__ipp_
|
data/rice/Data_Type_defn.hpp
CHANGED
|
@@ -39,7 +39,6 @@ public:
|
|
|
39
39
|
// Must be public to workaround gcc 3.3
|
|
40
40
|
typedef std::map<VALUE, detail::Abstract_Caster *> Casters;
|
|
41
41
|
|
|
42
|
-
protected:
|
|
43
42
|
virtual detail::Abstract_Caster * caster() const = 0;
|
|
44
43
|
|
|
45
44
|
static Casters & casters();
|
|
@@ -93,6 +92,15 @@ template<typename T, typename Base_T>
|
|
|
93
92
|
Rice::Data_Type<T> define_class(
|
|
94
93
|
char const * name);
|
|
95
94
|
|
|
95
|
+
//! Define an implicit conversion rule between two types.
|
|
96
|
+
/*! Given two types, which can be custom types already
|
|
97
|
+
* wrapped into Rice or fundamental C++ types, this
|
|
98
|
+
* tells Rice that the two types can be used interchangably.
|
|
99
|
+
* \param From_T The type to convert from
|
|
100
|
+
* \param To_T The type to convert to
|
|
101
|
+
*/
|
|
102
|
+
template<typename From_T, typename To_T>
|
|
103
|
+
void define_implicit_cast();
|
|
96
104
|
|
|
97
105
|
//! A mechanism for binding ruby types to C++ types.
|
|
98
106
|
/*! This class binds run-time types (Ruby VALUEs) to compile-time types
|
|
@@ -151,7 +159,13 @@ public:
|
|
|
151
159
|
*/
|
|
152
160
|
template<typename Constructor_T>
|
|
153
161
|
Data_Type<T> & define_constructor(
|
|
154
|
-
Constructor_T constructor
|
|
162
|
+
Constructor_T constructor,
|
|
163
|
+
Arguments * arguments = 0);
|
|
164
|
+
|
|
165
|
+
template<typename Constructor_T>
|
|
166
|
+
Data_Type<T> & define_constructor(
|
|
167
|
+
Constructor_T constructor,
|
|
168
|
+
Arg const& arg);
|
|
155
169
|
|
|
156
170
|
//! Register a Director class for this class.
|
|
157
171
|
/*! For any class that uses Rice::Director to enable polymorphism
|
|
@@ -188,6 +202,10 @@ public:
|
|
|
188
202
|
*/
|
|
189
203
|
static bool is_bound();
|
|
190
204
|
|
|
205
|
+
virtual detail::Abstract_Caster * caster() const;
|
|
206
|
+
|
|
207
|
+
static std::auto_ptr<detail::Abstract_Caster> caster_;
|
|
208
|
+
|
|
191
209
|
protected:
|
|
192
210
|
//! Bind a Data_Type to a VALUE.
|
|
193
211
|
/*! Throws an exception if the Data_Type is already bound to a
|
|
@@ -221,12 +239,9 @@ private:
|
|
|
221
239
|
template<typename T_>
|
|
222
240
|
friend class Data_Type;
|
|
223
241
|
|
|
224
|
-
virtual detail::Abstract_Caster * caster() const;
|
|
225
|
-
|
|
226
242
|
static void check_is_bound();
|
|
227
243
|
|
|
228
244
|
static VALUE klass_;
|
|
229
|
-
static std::auto_ptr<detail::Abstract_Caster> caster_;
|
|
230
245
|
|
|
231
246
|
typedef std::set<Data_Type<T> *> Instances;
|
|
232
247
|
|
data/rice/config.hpp
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
/* rice/config.hpp.in. Generated from configure.ac by autoheader. */
|
|
3
3
|
|
|
4
4
|
/* Define to 1 if you have the <env.h> header file. */
|
|
5
|
-
#
|
|
5
|
+
/* #undef HAVE_ENV_H */
|
|
6
6
|
|
|
7
7
|
/* Define to 1 if you have the <node.h> header file. */
|
|
8
|
-
#
|
|
8
|
+
/* #undef HAVE_NODE_H */
|
|
9
9
|
|
|
10
10
|
/* Define to 1 if you have the <ruby.h> header file. */
|
|
11
11
|
#define HAVE_RUBY_H 1
|
|
12
12
|
|
|
13
13
|
/* Define to 1 if you have the <ruby/node.h> header file. */
|
|
14
|
-
#
|
|
14
|
+
/* #undef HAVE_RUBY_NODE_H */
|
|
15
15
|
|
|
16
16
|
/* Define to 1 if you have the <version.h> header file. */
|
|
17
|
-
#
|
|
17
|
+
/* #undef HAVE_VERSION_H */
|
|
18
18
|
|
|
19
19
|
/* Name of package */
|
|
20
20
|
#define PACKAGE "rice"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
#define PACKAGE_VERSION "1.1"
|
|
36
36
|
|
|
37
37
|
/* Define this macro to use ruby/node.h */
|
|
38
|
-
#
|
|
38
|
+
/* #undef REALLY_HAVE_RUBY_NODE_H */
|
|
39
39
|
|
|
40
40
|
/* Version number of package */
|
|
41
41
|
#define VERSION "1.1"
|
data/rice/detail/Caster.hpp
CHANGED
|
@@ -56,6 +56,46 @@ private:
|
|
|
56
56
|
Module type_;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
template<typename To_T, typename From_T>
|
|
60
|
+
class Implicit_Caster
|
|
61
|
+
: public Abstract_Caster
|
|
62
|
+
{
|
|
63
|
+
public:
|
|
64
|
+
Implicit_Caster(Abstract_Caster * base_caster, Module type)
|
|
65
|
+
: base_caster_(base_caster)
|
|
66
|
+
, type_(type)
|
|
67
|
+
{
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
protected:
|
|
71
|
+
virtual void * cast_to_base(void * derived, Module type) const
|
|
72
|
+
{
|
|
73
|
+
if(type.value() == type_.value())
|
|
74
|
+
{
|
|
75
|
+
return new To_T( *static_cast<From_T*>(derived) );
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
{
|
|
79
|
+
if(base_caster_)
|
|
80
|
+
{
|
|
81
|
+
return base_caster_->cast_to_base(derived, type);
|
|
82
|
+
}
|
|
83
|
+
else
|
|
84
|
+
{
|
|
85
|
+
std::string s = "bad cast. No implicit caster found for ";
|
|
86
|
+
s += type_.name().str();
|
|
87
|
+
throw std::runtime_error(s);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private:
|
|
93
|
+
Abstract_Caster * base_caster_;
|
|
94
|
+
Module type_;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
59
99
|
} // detail
|
|
60
100
|
|
|
61
101
|
} // Rice
|
data/rice/detail/to_ruby.ipp
CHANGED
data/rice/ruby_mark.hpp
CHANGED
data/ruby/lib/mkmf-rice.rb.in
CHANGED
data/ruby/lib/version.rb
CHANGED
data/sample/enum/test.rb
CHANGED
data/test/Makefile.am
CHANGED
|
@@ -46,6 +46,7 @@ unittest_SOURCES = \
|
|
|
46
46
|
test_Hash.cpp \
|
|
47
47
|
test_Identifier.cpp \
|
|
48
48
|
test_Jump_Tag.cpp \
|
|
49
|
+
test_Memory_Management.cpp \
|
|
49
50
|
test_Module.cpp \
|
|
50
51
|
test_Object.cpp \
|
|
51
52
|
test_String.cpp \
|
|
@@ -60,6 +61,7 @@ vm_unittest_SOURCES = \
|
|
|
60
61
|
|
|
61
62
|
AM_CPPFLAGS = \
|
|
62
63
|
-I.. \
|
|
64
|
+
$(RUBY_CFLAGS)
|
|
63
65
|
$(RUBY_CPPFLAGS)
|
|
64
66
|
|
|
65
67
|
AM_CXXLAGS = \
|
data/test/Makefile.in
CHANGED
|
@@ -54,10 +54,10 @@ am_unittest_OBJECTS = unittest.$(OBJEXT) \
|
|
|
54
54
|
test_Director.$(OBJEXT) test_Enum.$(OBJEXT) \
|
|
55
55
|
test_Exception.$(OBJEXT) test_Hash.$(OBJEXT) \
|
|
56
56
|
test_Identifier.$(OBJEXT) test_Jump_Tag.$(OBJEXT) \
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
test_global_functions.$(OBJEXT)
|
|
57
|
+
test_Memory_Management.$(OBJEXT) test_Module.$(OBJEXT) \
|
|
58
|
+
test_Object.$(OBJEXT) test_String.$(OBJEXT) \
|
|
59
|
+
test_Struct.$(OBJEXT) test_Symbol.$(OBJEXT) \
|
|
60
|
+
test_To_From_Ruby.$(OBJEXT) test_global_functions.$(OBJEXT)
|
|
61
61
|
unittest_OBJECTS = $(am_unittest_OBJECTS)
|
|
62
62
|
unittest_LDADD = $(LDADD)
|
|
63
63
|
am_vm_unittest_OBJECTS = unittest.$(OBJEXT) test_VM.$(OBJEXT)
|
|
@@ -237,6 +237,7 @@ unittest_SOURCES = \
|
|
|
237
237
|
test_Hash.cpp \
|
|
238
238
|
test_Identifier.cpp \
|
|
239
239
|
test_Jump_Tag.cpp \
|
|
240
|
+
test_Memory_Management.cpp \
|
|
240
241
|
test_Module.cpp \
|
|
241
242
|
test_Object.cpp \
|
|
242
243
|
test_String.cpp \
|
|
@@ -251,7 +252,7 @@ vm_unittest_SOURCES = \
|
|
|
251
252
|
|
|
252
253
|
AM_CPPFLAGS = \
|
|
253
254
|
-I.. \
|
|
254
|
-
$(
|
|
255
|
+
$(RUBY_CFLAGS)
|
|
255
256
|
|
|
256
257
|
AM_CXXLAGS = \
|
|
257
258
|
$(RUBY_CXXFLAGS)
|
|
@@ -324,6 +325,7 @@ distclean-compile:
|
|
|
324
325
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_Hash.Po@am__quote@
|
|
325
326
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_Identifier.Po@am__quote@
|
|
326
327
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_Jump_Tag.Po@am__quote@
|
|
328
|
+
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_Memory_Management.Po@am__quote@
|
|
327
329
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_Module.Po@am__quote@
|
|
328
330
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_Object.Po@am__quote@
|
|
329
331
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_String.Po@am__quote@
|
|
@@ -720,6 +722,7 @@ check: run_multiple_extensions_same_class_test
|
|
|
720
722
|
|
|
721
723
|
run_multiple_extensions_same_class_test:
|
|
722
724
|
$(RUBY) test_multiple_extensions_same_class.rb
|
|
725
|
+
$(RUBY_CPPFLAGS)
|
|
723
726
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
724
727
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
725
728
|
.NOEXPORT:
|
data/test/test_Constructor.cpp
CHANGED
|
@@ -65,63 +65,64 @@ TESTCASE(non_default_constructor)
|
|
|
65
65
|
ASSERT_EQUAL(42, o->i());
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
/*
|
|
69
68
|
namespace
|
|
70
69
|
{
|
|
70
|
+
int withArgsX;
|
|
71
|
+
float withArgsY;
|
|
72
|
+
bool withArgsYes;
|
|
73
|
+
|
|
71
74
|
class WithDefaultArgs
|
|
72
75
|
{
|
|
73
76
|
public:
|
|
74
77
|
WithDefaultArgs(int x, float y = 2.0, bool yes = false)
|
|
75
78
|
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
withArgsX = x;
|
|
80
|
+
withArgsY = y;
|
|
81
|
+
withArgsYes = yes;
|
|
79
82
|
}
|
|
83
|
+
};
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
int withArgX;
|
|
86
|
+
class WithOneArg
|
|
87
|
+
{
|
|
88
|
+
public:
|
|
89
|
+
WithOneArg(int x = 14) {
|
|
90
|
+
withArgX = x;
|
|
85
91
|
}
|
|
86
|
-
|
|
87
|
-
int getX() { return x_; }
|
|
88
|
-
float getY() { return y_; }
|
|
89
|
-
bool getYes() { return yes_; }
|
|
90
|
-
|
|
91
|
-
private:
|
|
92
|
-
|
|
93
|
-
int x_;
|
|
94
|
-
float y_;
|
|
95
|
-
bool yes_;
|
|
96
92
|
};
|
|
97
93
|
}
|
|
98
94
|
|
|
99
95
|
TESTCASE(constructor_supports_default_arguments)
|
|
100
96
|
{
|
|
101
97
|
Class klass = define_class<WithDefaultArgs>("WithDefaultArgs").
|
|
102
|
-
define_constructor(Constructor<WithDefaultArgs, int, float, bool>(
|
|
103
|
-
( Arg("x"), Arg("y") = (float)2.0, Arg("yes") = (bool)false ))
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
ASSERT_EQUAL(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
ASSERT_EQUAL(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
ASSERT_EQUAL(
|
|
119
|
-
ASSERT_EQUAL(12.0, obj->getY());
|
|
120
|
-
ASSERT_EQUAL(true, obj->getYes());
|
|
98
|
+
define_constructor(Constructor<WithDefaultArgs, int, float, bool>(),
|
|
99
|
+
( Arg("x"), Arg("y") = (float)2.0, Arg("yes") = (bool)false ));
|
|
100
|
+
|
|
101
|
+
klass.call("new", 4);
|
|
102
|
+
ASSERT_EQUAL(4, withArgsX);
|
|
103
|
+
ASSERT_EQUAL(2.0, withArgsY);
|
|
104
|
+
ASSERT_EQUAL(false, withArgsYes);
|
|
105
|
+
|
|
106
|
+
klass.call("new", 5, 3.0);
|
|
107
|
+
ASSERT_EQUAL(5, withArgsX);
|
|
108
|
+
ASSERT_EQUAL(3.0, withArgsY);
|
|
109
|
+
ASSERT_EQUAL(false, withArgsYes);
|
|
110
|
+
|
|
111
|
+
klass.call("new", 7, 12.0, true);
|
|
112
|
+
ASSERT_EQUAL(7, withArgsX);
|
|
113
|
+
ASSERT_EQUAL(12.0, withArgsY);
|
|
114
|
+
ASSERT_EQUAL(true, withArgsYes);
|
|
121
115
|
}
|
|
122
116
|
|
|
123
117
|
TESTCASE(constructor_supports_single_default_argument)
|
|
124
118
|
{
|
|
119
|
+
Class klass = define_class<WithOneArg>("WithOneArg").
|
|
120
|
+
define_constructor(Constructor<WithOneArg, int>(),
|
|
121
|
+
( Arg("x") = 14 ));
|
|
122
|
+
|
|
123
|
+
klass.call("new");
|
|
124
|
+
ASSERT_EQUAL(14, withArgX);
|
|
125
125
|
|
|
126
|
+
klass.call("new", 6);
|
|
127
|
+
ASSERT_EQUAL(6, withArgX);
|
|
126
128
|
}
|
|
127
|
-
*/
|
data/test/test_Data_Type.cpp
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include "rice/Data_Type.hpp"
|
|
3
3
|
#include "rice/Exception.hpp"
|
|
4
4
|
#include "rice/Constructor.hpp"
|
|
5
|
+
#include "rice/global_function.hpp"
|
|
5
6
|
|
|
6
7
|
using namespace Rice;
|
|
7
8
|
|
|
@@ -119,3 +120,229 @@ TESTCASE(no_super_in_constructor_still_works)
|
|
|
119
120
|
ASSERT_EQUAL(INT2NUM(8), handler.call("process").value());
|
|
120
121
|
}
|
|
121
122
|
*/
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Implicit Casting across unrelated types
|
|
126
|
+
*
|
|
127
|
+
* Two ways of defining if types are implicitly castable
|
|
128
|
+
*
|
|
129
|
+
* 1) operator
|
|
130
|
+
* 2) constructor
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Examples here taken from Ogre's Math library.
|
|
135
|
+
* This uses the constructor method of casting types.
|
|
136
|
+
*/
|
|
137
|
+
namespace
|
|
138
|
+
{
|
|
139
|
+
const int degree2Radians = (3.14 / 180.0);
|
|
140
|
+
const int radian2Degrees = (180.0 / 3.14);
|
|
141
|
+
|
|
142
|
+
class Radian;
|
|
143
|
+
|
|
144
|
+
class Degree
|
|
145
|
+
{
|
|
146
|
+
public:
|
|
147
|
+
explicit Degree(float d) : val_(d) {}
|
|
148
|
+
Degree(const Radian& r);
|
|
149
|
+
|
|
150
|
+
float valueDegrees() const { return val_; }
|
|
151
|
+
float valueRadians() const { return val_ * degree2Radians; }
|
|
152
|
+
|
|
153
|
+
private:
|
|
154
|
+
float val_;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
class Radian
|
|
158
|
+
{
|
|
159
|
+
public:
|
|
160
|
+
explicit Radian(float r) : val_(r) {}
|
|
161
|
+
Radian(const Degree& d) : val_(d.valueRadians()) {}
|
|
162
|
+
|
|
163
|
+
float valueRadians() const { return val_; }
|
|
164
|
+
float valueDegrees() const { return val_ * radian2Degrees; }
|
|
165
|
+
|
|
166
|
+
private:
|
|
167
|
+
float val_;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// Due to circular dependencies, need to define some
|
|
171
|
+
// methods down here
|
|
172
|
+
Degree::Degree(const Radian& r)
|
|
173
|
+
{
|
|
174
|
+
val_ = r.valueDegrees();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* And now some methods that work w/ the above two classes
|
|
179
|
+
*/
|
|
180
|
+
bool isAcute(Degree degree) {
|
|
181
|
+
return degree.valueDegrees() < 90;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
bool isObtuse(Radian radian) {
|
|
185
|
+
return radian.valueDegrees() > 90 && radian.valueDegrees() <= 180;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
bool isRight(Degree* degree) {
|
|
189
|
+
return degree->valueDegrees() == 90;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
TESTCASE(can_define_implicit_type_conversions_across_wrapped_types)
|
|
194
|
+
{
|
|
195
|
+
define_class<Degree>("Degree")
|
|
196
|
+
.define_constructor(Constructor<Degree, float>());
|
|
197
|
+
|
|
198
|
+
define_class<Radian>("Radian")
|
|
199
|
+
.define_constructor(Constructor<Radian, float>());
|
|
200
|
+
|
|
201
|
+
define_implicit_cast<Degree, Radian>();
|
|
202
|
+
define_implicit_cast<Radian, Degree>();
|
|
203
|
+
|
|
204
|
+
define_global_function("is_acute", &isAcute);
|
|
205
|
+
define_global_function("is_obtuse", &isObtuse);
|
|
206
|
+
define_global_function("is_right", &isRight);
|
|
207
|
+
|
|
208
|
+
Module m = define_module("TestingModule");
|
|
209
|
+
Object result;
|
|
210
|
+
|
|
211
|
+
// ACUTE
|
|
212
|
+
result = m.instance_eval("is_acute(Degree.new(75))");
|
|
213
|
+
ASSERT(from_ruby<bool>(result.value()));
|
|
214
|
+
|
|
215
|
+
result = m.instance_eval("is_acute(Radian.new(2.0))");
|
|
216
|
+
ASSERT(!from_ruby<bool>(result.value()));
|
|
217
|
+
|
|
218
|
+
// OBTUSE
|
|
219
|
+
result = m.instance_eval("is_obtuse(Degree.new(75))");
|
|
220
|
+
ASSERT(!from_ruby<bool>(result.value()));
|
|
221
|
+
|
|
222
|
+
result = m.instance_eval("is_obtuse(Radian.new(2.0))");
|
|
223
|
+
ASSERT(from_ruby<bool>(result.value()));
|
|
224
|
+
|
|
225
|
+
// RIGHT
|
|
226
|
+
result = m.instance_eval("is_right(Degree.new(90))");
|
|
227
|
+
ASSERT(from_ruby<bool>(result.value()));
|
|
228
|
+
|
|
229
|
+
result = m.instance_eval("is_right(Radian.new(2.0))");
|
|
230
|
+
ASSERT(!from_ruby<bool>(result.value()));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
namespace {
|
|
234
|
+
class Explicit
|
|
235
|
+
{
|
|
236
|
+
public:
|
|
237
|
+
Explicit(float v) {
|
|
238
|
+
value = v;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
Explicit(const Degree &d) {
|
|
242
|
+
value = d.valueDegrees();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
float getValue() { return value; }
|
|
246
|
+
|
|
247
|
+
private:
|
|
248
|
+
float value;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
float getExplicitValue(Explicit* v) {
|
|
252
|
+
return v->getValue();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
TESTCASE(supports_multiple_implicit_conversions_for_a_type)
|
|
257
|
+
{
|
|
258
|
+
define_class<Degree>("Degree")
|
|
259
|
+
.define_constructor(Constructor<Degree, float>());
|
|
260
|
+
|
|
261
|
+
define_class<Radian>("Radian")
|
|
262
|
+
.define_constructor(Constructor<Radian, float>());
|
|
263
|
+
|
|
264
|
+
define_class<Explicit>("Explicit")
|
|
265
|
+
.define_constructor(Constructor<Explicit, float>());
|
|
266
|
+
|
|
267
|
+
define_global_function("is_obtuse", &isObtuse);
|
|
268
|
+
define_global_function("explicit_value", &getExplicitValue);
|
|
269
|
+
|
|
270
|
+
define_implicit_cast<Radian, Degree>();
|
|
271
|
+
define_implicit_cast<Degree, Radian>();
|
|
272
|
+
define_implicit_cast<Degree, Explicit>();
|
|
273
|
+
|
|
274
|
+
Module m = define_module("TestingModule");
|
|
275
|
+
Object result;
|
|
276
|
+
|
|
277
|
+
result = m.instance_eval("is_obtuse(Degree.new(75))");
|
|
278
|
+
ASSERT(!from_ruby<bool>(result.value()));
|
|
279
|
+
|
|
280
|
+
result = m.instance_eval("explicit_value(Degree.new(75))");
|
|
281
|
+
ASSERT_EQUAL(75.0, from_ruby<float>(result.value()));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Sample taken and modified from boost::python::implicit:
|
|
286
|
+
* http://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/implicit.html
|
|
287
|
+
*
|
|
288
|
+
* This is the operator version of casting and shows that this works for
|
|
289
|
+
* base types as well as defined types
|
|
290
|
+
*/
|
|
291
|
+
/*
|
|
292
|
+
namespace {
|
|
293
|
+
struct Real
|
|
294
|
+
{
|
|
295
|
+
Real(int x)
|
|
296
|
+
: v(x)
|
|
297
|
+
{}
|
|
298
|
+
|
|
299
|
+
operator int() const
|
|
300
|
+
{
|
|
301
|
+
return v;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
int v;
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
int realValue(Real const& x)
|
|
308
|
+
{
|
|
309
|
+
return x.v;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
Real makeReal(int n)
|
|
313
|
+
{
|
|
314
|
+
return Real(n);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
TESTCASE(can_define_implicit_type_conversions_to_base_types)
|
|
319
|
+
{
|
|
320
|
+
define_class<Real>("Real")
|
|
321
|
+
.define_constructor(Constructor<Real, int>());
|
|
322
|
+
|
|
323
|
+
// Define the conversion rules
|
|
324
|
+
define_implicit_cast<Real, int>();
|
|
325
|
+
define_implicit_cast<int, Real>();
|
|
326
|
+
|
|
327
|
+
define_global_function("real_value", &realValue);
|
|
328
|
+
define_global_function("make_real", &makeReal);
|
|
329
|
+
|
|
330
|
+
Module m = define_module("TestingModule");
|
|
331
|
+
|
|
332
|
+
// As Real object
|
|
333
|
+
Object result = m.instance_eval("real_value( Real.new(4) )");
|
|
334
|
+
ASSERT_EQUAL(4, from_ruby<int>(result.value()));
|
|
335
|
+
|
|
336
|
+
// As fixnum (int)
|
|
337
|
+
result = m.instance_eval("real_value(4)");
|
|
338
|
+
ASSERT_EQUAL(4, from_ruby<int>(result.value()));
|
|
339
|
+
|
|
340
|
+
// As Real object
|
|
341
|
+
result = m.instance_eval("r = make_real( Real.new(6) ); real_value(r)");
|
|
342
|
+
ASSERT_EQUAL(6, from_ruby<int>(result.value()));
|
|
343
|
+
|
|
344
|
+
// As fixnum (int)
|
|
345
|
+
result = m.instance_eval("r = make_real(6); real_value(r)");
|
|
346
|
+
ASSERT_EQUAL(6, from_ruby<int>(result.value()));
|
|
347
|
+
}
|
|
348
|
+
*/
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#include "unittest.hpp"
|
|
2
|
+
#include "rice/String.hpp"
|
|
3
|
+
#include "rice/Class.hpp"
|
|
4
|
+
#include "rice/global_function.hpp"
|
|
5
|
+
|
|
6
|
+
using namespace Rice;
|
|
7
|
+
|
|
8
|
+
TESTSUITE(Memory_Management);
|
|
9
|
+
|
|
10
|
+
SETUP(Memory_Management)
|
|
11
|
+
{
|
|
12
|
+
ruby_init();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
namespace
|
|
16
|
+
{
|
|
17
|
+
class TestClass {
|
|
18
|
+
double tmp;
|
|
19
|
+
public:
|
|
20
|
+
TestClass() {tmp=0;}
|
|
21
|
+
|
|
22
|
+
double getTmp() {
|
|
23
|
+
return tmp;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void setTmp(double x) {
|
|
27
|
+
tmp = x;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
TestClass returnTestClass() {
|
|
32
|
+
TestClass x = TestClass();
|
|
33
|
+
x.setTmp(8);
|
|
34
|
+
return x;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
TESTCASE(allows_copy_contructors_to_work)
|
|
39
|
+
{
|
|
40
|
+
define_class<TestClass>("TestClass")
|
|
41
|
+
.define_method("tmp=", &TestClass::setTmp)
|
|
42
|
+
.define_method("tmp", &TestClass::getTmp);
|
|
43
|
+
|
|
44
|
+
define_global_function("return_test_class", &returnTestClass);
|
|
45
|
+
|
|
46
|
+
Module m = define_module("TestingModule");
|
|
47
|
+
|
|
48
|
+
Object result = m.instance_eval("return_test_class.tmp");
|
|
49
|
+
ASSERT_EQUAL(8.0, from_ruby<double>(result.value()));
|
|
50
|
+
}
|
metadata
CHANGED
|
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
|
4
4
|
prerelease: false
|
|
5
5
|
segments:
|
|
6
6
|
- 1
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
version: 1.
|
|
7
|
+
- 4
|
|
8
|
+
- 0
|
|
9
|
+
version: 1.4.0
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Paul Brannan
|
|
@@ -15,13 +15,14 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2010-
|
|
18
|
+
date: 2010-08-25 00:00:00 -04:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies:
|
|
21
21
|
- !ruby/object:Gem::Dependency
|
|
22
22
|
name: rubyforge
|
|
23
23
|
prerelease: false
|
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
25
26
|
requirements:
|
|
26
27
|
- - ">="
|
|
27
28
|
- !ruby/object:Gem::Version
|
|
@@ -230,6 +231,7 @@ files:
|
|
|
230
231
|
- test/test_Hash.cpp
|
|
231
232
|
- test/test_Identifier.cpp
|
|
232
233
|
- test/test_Jump_Tag.cpp
|
|
234
|
+
- test/test_Memory_Management.cpp
|
|
233
235
|
- test/test_Module.cpp
|
|
234
236
|
- test/test_Object.cpp
|
|
235
237
|
- test/test_String.cpp
|
|
@@ -246,6 +248,7 @@ files:
|
|
|
246
248
|
- test/ext/t1/t1.cpp
|
|
247
249
|
- test/ext/t2/extconf.rb
|
|
248
250
|
- test/ext/t2/t2.cpp
|
|
251
|
+
- test/test_rice.rb
|
|
249
252
|
has_rdoc: true
|
|
250
253
|
homepage: http://rice.rubyforge.org/
|
|
251
254
|
licenses: []
|
|
@@ -256,6 +259,7 @@ rdoc_options: []
|
|
|
256
259
|
require_paths:
|
|
257
260
|
- ruby/lib
|
|
258
261
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
262
|
+
none: false
|
|
259
263
|
requirements:
|
|
260
264
|
- - ">="
|
|
261
265
|
- !ruby/object:Gem::Version
|
|
@@ -263,6 +267,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
263
267
|
- 0
|
|
264
268
|
version: "0"
|
|
265
269
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
270
|
+
none: false
|
|
266
271
|
requirements:
|
|
267
272
|
- - ">="
|
|
268
273
|
- !ruby/object:Gem::Version
|
|
@@ -272,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
272
277
|
requirements: []
|
|
273
278
|
|
|
274
279
|
rubyforge_project: rice
|
|
275
|
-
rubygems_version: 1.3.
|
|
280
|
+
rubygems_version: 1.3.7
|
|
276
281
|
signing_key:
|
|
277
282
|
specification_version: 3
|
|
278
283
|
summary: Ruby Interface for C++ Extensions
|