extpp 0.0.1
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 +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +48 -0
- data/doc/text/news.md +5 -0
- data/ext/extpp/class.cpp +261 -0
- data/ext/extpp/extconf.rb +75 -0
- data/ext/extpp/function.cpp +28 -0
- data/ext/extpp/object.cpp +45 -0
- data/include/ruby.hpp +10 -0
- data/include/ruby/cast.hpp +74 -0
- data/include/ruby/class.hpp +25 -0
- data/include/ruby/object.hpp +96 -0
- data/include/ruby/type.hpp +12 -0
- data/lib/extpp.rb +36 -0
- data/lib/extpp/compiler.rb +69 -0
- data/lib/extpp/version.rb +3 -0
- data/test/fixtures/cast/cast.cpp +32 -0
- data/test/fixtures/cast/extconf.rb +4 -0
- data/test/fixtures/class/class.cpp +46 -0
- data/test/fixtures/class/extconf.rb +4 -0
- data/test/fixtures/object/extconf.rb +4 -0
- data/test/fixtures/object/object.cpp +78 -0
- data/test/helper.rb +9 -0
- data/test/run-test.rb +23 -0
- data/test/test-cast.rb +42 -0
- data/test/test-class.rb +47 -0
- data/test/test-object.rb +52 -0
- metadata +169 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
#include <ruby.hpp>
|
2
|
+
|
3
|
+
namespace {
|
4
|
+
VALUE rb_hello(VALUE self) {
|
5
|
+
return rb_str_new_cstr("Hello");
|
6
|
+
}
|
7
|
+
|
8
|
+
VALUE rb_named_hello(int argc, VALUE *argv, VALUE self) {
|
9
|
+
VALUE rb_name;
|
10
|
+
rb_scan_args(argc, argv, "10", &rb_name);
|
11
|
+
return rb_str_plus(rb_str_new_cstr("Hello "), rb_name);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
extern "C" void
|
16
|
+
Init_class(void)
|
17
|
+
{
|
18
|
+
rb::Class("Greeting").
|
19
|
+
define_method("hello", [](VALUE self) {
|
20
|
+
return rb_str_new_cstr("Hello");
|
21
|
+
}).
|
22
|
+
enable_lazy_define_method().
|
23
|
+
define_method("hello_lazy", [](VALUE self) {
|
24
|
+
return rb_str_new_cstr("Hello");
|
25
|
+
}).
|
26
|
+
define_method("hello_defined", rb_hello);
|
27
|
+
|
28
|
+
rb::Class("NamedGreeting").
|
29
|
+
define_method("hello", [](VALUE self, int argc, VALUE *argv) {
|
30
|
+
VALUE rb_name;
|
31
|
+
rb_scan_args(argc, argv, "10", &rb_name);
|
32
|
+
return rb_str_plus(rb_str_new_cstr("Hello "), rb_name);
|
33
|
+
}).
|
34
|
+
define_method("hello_compatible", [](int argc, VALUE *argv, VALUE self) {
|
35
|
+
VALUE rb_name;
|
36
|
+
rb_scan_args(argc, argv, "10", &rb_name);
|
37
|
+
return rb_str_plus(rb_str_new_cstr("Hello "), rb_name);
|
38
|
+
}).
|
39
|
+
enable_lazy_define_method().
|
40
|
+
define_method("hello_lazy", [](VALUE self, int argc, VALUE *argv) {
|
41
|
+
VALUE rb_name;
|
42
|
+
rb_scan_args(argc, argv, "10", &rb_name);
|
43
|
+
return rb_str_plus(rb_str_new_cstr("Hello "), rb_name);
|
44
|
+
}).
|
45
|
+
define_method("hello_defined", rb_named_hello);
|
46
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#include <ruby.hpp>
|
2
|
+
|
3
|
+
extern "C" void
|
4
|
+
Init_object(void)
|
5
|
+
{
|
6
|
+
rb::Class("ObjectMethods").
|
7
|
+
define_method("to_bool_true", [](VALUE self) {
|
8
|
+
rb::Object object(Qtrue);
|
9
|
+
if (object) {
|
10
|
+
return Qtrue;
|
11
|
+
} else {
|
12
|
+
return Qfalse;
|
13
|
+
}
|
14
|
+
}).
|
15
|
+
define_method("to_bool_false", [](VALUE self) {
|
16
|
+
rb::Object object(Qfalse);
|
17
|
+
if (object) {
|
18
|
+
return Qtrue;
|
19
|
+
} else {
|
20
|
+
return Qfalse;
|
21
|
+
}
|
22
|
+
}).
|
23
|
+
define_method("to_bool_nil", [](VALUE self) {
|
24
|
+
rb::Object object(Qnil);
|
25
|
+
if (object) {
|
26
|
+
return Qtrue;
|
27
|
+
} else {
|
28
|
+
return Qfalse;
|
29
|
+
}
|
30
|
+
}).
|
31
|
+
define_method("to_ruby", [](int argc, VALUE *argv, VALUE self) {
|
32
|
+
VALUE rb_object;
|
33
|
+
rb_scan_args(argc, argv, "1", &rb_object);
|
34
|
+
rb::Object object(rb_object);
|
35
|
+
return static_cast<VALUE>(object);
|
36
|
+
}).
|
37
|
+
define_method("send_no_arguments", [](int argc, VALUE *argv, VALUE self) {
|
38
|
+
VALUE rb_receiver;
|
39
|
+
VALUE rb_method_name;
|
40
|
+
rb_scan_args(argc, argv, "2", &rb_receiver, &rb_method_name);
|
41
|
+
rb::Object receiver(rb_receiver);
|
42
|
+
rb::Object method_name(rb_method_name);
|
43
|
+
auto result = receiver.send(method_name);
|
44
|
+
return static_cast<VALUE>(result);
|
45
|
+
}).
|
46
|
+
define_method("send_two_arguments", [](int argc, VALUE *argv, VALUE self) {
|
47
|
+
VALUE rb_receiver;
|
48
|
+
VALUE rb_method_name;
|
49
|
+
VALUE rb_arg1;
|
50
|
+
VALUE rb_arg2;
|
51
|
+
rb_scan_args(argc, argv, "4",
|
52
|
+
&rb_receiver,
|
53
|
+
&rb_method_name,
|
54
|
+
&rb_arg1,
|
55
|
+
&rb_arg2);
|
56
|
+
rb::Object receiver(rb_receiver);
|
57
|
+
rb::Object method_name(rb_method_name);
|
58
|
+
auto result = receiver.send(method_name, {rb_arg1, rb_arg2});
|
59
|
+
return static_cast<VALUE>(result);
|
60
|
+
}).
|
61
|
+
define_method("send_block", [](int argc, VALUE *argv, VALUE self) {
|
62
|
+
VALUE rb_receiver;
|
63
|
+
VALUE rb_method_name;
|
64
|
+
rb_scan_args(argc, argv, "2",
|
65
|
+
&rb_receiver,
|
66
|
+
&rb_method_name);
|
67
|
+
rb::Object receiver(rb_receiver);
|
68
|
+
rb::Object method_name(rb_method_name);
|
69
|
+
auto result = receiver.send(method_name,
|
70
|
+
{},
|
71
|
+
[](VALUE rb_n) -> VALUE {
|
72
|
+
auto n = rb::Object(rb_n);
|
73
|
+
auto n_raw = rb::cast<int32_t>(n);
|
74
|
+
return rb::cast<rb::Object>(n_raw * n_raw);
|
75
|
+
});
|
76
|
+
return static_cast<VALUE>(result);
|
77
|
+
});
|
78
|
+
}
|
data/test/helper.rb
ADDED
data/test/run-test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$VERBOSE = true
|
4
|
+
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
base_dir = Pathname.new(__dir__).parent.expand_path
|
8
|
+
|
9
|
+
ext_dir = base_dir + "ext" + "extpp"
|
10
|
+
lib_dir = base_dir + "lib"
|
11
|
+
test_dir = base_dir + "test"
|
12
|
+
|
13
|
+
Dir.chdir(ext_dir.to_s) do
|
14
|
+
if File.exist?("Makefile")
|
15
|
+
system("make > /dev/null") or exit(false)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
$LOAD_PATH.unshift(lib_dir.to_s)
|
20
|
+
|
21
|
+
require_relative "helper"
|
22
|
+
|
23
|
+
exit(Test::Unit::AutoRunner.run(true, test_dir.to_s))
|
data/test/test-cast.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
class CastTest < Test::Unit::TestCase
|
2
|
+
extend Helper::Fixture
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def startup
|
6
|
+
lib_dir = File.join(__dir__, "..", "lib")
|
7
|
+
Dir.chdir(fixture_path("cast")) do
|
8
|
+
system(RbConfig.ruby, "-w", "-I", lib_dir, "extconf.rb")
|
9
|
+
system("make")
|
10
|
+
end
|
11
|
+
require fixture_path("cast", "cast")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@caster = Caster.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_int32
|
20
|
+
assert_equal(-(2 ** 31),
|
21
|
+
@caster.cast_int32(-(2 ** 31)))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_int64
|
25
|
+
assert_equal(-(2 ** 63),
|
26
|
+
@caster.cast_int64(-(2 ** 63)))
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_uint32
|
30
|
+
assert_equal(2 ** 32 - 1,
|
31
|
+
@caster.cast_uint32(2 ** 32 - 1))
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_uint64
|
35
|
+
assert_equal(2 ** 64 - 1,
|
36
|
+
@caster.cast_uint64(2 ** 64 - 1))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_string
|
40
|
+
assert_equal("Hello", @caster.cast_string("Hello"))
|
41
|
+
end
|
42
|
+
end
|
data/test/test-class.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
class ClassTest < Test::Unit::TestCase
|
2
|
+
extend Helper::Fixture
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def startup
|
6
|
+
return unless self == ClassTest
|
7
|
+
lib_dir = File.join(__dir__, "..", "lib")
|
8
|
+
Dir.chdir(fixture_path("class")) do
|
9
|
+
system(RbConfig.ruby, "-w", "-I", lib_dir, "extconf.rb")
|
10
|
+
system("make")
|
11
|
+
end
|
12
|
+
require fixture_path("class", "class")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
sub_test_case("no argument") do
|
17
|
+
def test_define_method
|
18
|
+
assert_equal("Hello", Greeting.new.hello)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_define_method_lazy
|
22
|
+
assert_equal("Hello", Greeting.new.hello_lazy)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_define_method_defined
|
26
|
+
assert_equal("Hello", Greeting.new.hello_defined)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
sub_test_case("with arguments") do
|
31
|
+
def test_define_method
|
32
|
+
assert_equal("Hello Ruby", NamedGreeting.new.hello("Ruby"))
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_define_method_compatible
|
36
|
+
assert_equal("Hello Ruby", NamedGreeting.new.hello_compatible("Ruby"))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_define_method_lazy
|
40
|
+
assert_equal("Hello Ruby", NamedGreeting.new.hello_lazy("Ruby"))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_define_method_defined
|
44
|
+
assert_equal("Hello Ruby", NamedGreeting.new.hello_defined("Ruby"))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/test/test-object.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class ObjectTest < Test::Unit::TestCase
|
2
|
+
extend Helper::Fixture
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def startup
|
6
|
+
return unless self == ObjectTest
|
7
|
+
lib_dir = File.join(__dir__, "..", "lib")
|
8
|
+
Dir.chdir(fixture_path("object")) do
|
9
|
+
system(RbConfig.ruby, "-w", "-I", lib_dir, "extconf.rb")
|
10
|
+
system("make")
|
11
|
+
end
|
12
|
+
require fixture_path("object", "object")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
sub_test_case("to_bool") do
|
17
|
+
def test_true
|
18
|
+
assert_equal(true, ObjectMethods.new.to_bool_true)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_false
|
22
|
+
assert_equal(false, ObjectMethods.new.to_bool_false)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_nil
|
26
|
+
assert_equal(false, ObjectMethods.new.to_bool_nil)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_to_ruby
|
31
|
+
assert_equal("Hello", ObjectMethods.new.to_ruby("Hello"))
|
32
|
+
end
|
33
|
+
|
34
|
+
sub_test_case("send") do
|
35
|
+
def test_no_arguments
|
36
|
+
assert_equal("1", ObjectMethods.new.send_no_arguments(1, "to_s"))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_two_arguments
|
40
|
+
assert_equal("ell",
|
41
|
+
ObjectMethods.new.send_two_arguments("hello",
|
42
|
+
"[]",
|
43
|
+
1,
|
44
|
+
3))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_block
|
48
|
+
assert_equal([1, 4, 9],
|
49
|
+
ObjectMethods.new.send_block([1, 2, 3], "collect"))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: extpp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kouhei Sutou
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-02-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: kramdown
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: packnga
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: test-unit
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: |-
|
98
|
+
You can write your Ruby extension easier than Ruby's C API. Because
|
99
|
+
Ext++'s C++ API reduces duplicated code needed for Ruby's C API.
|
100
|
+
email:
|
101
|
+
- kou@clear-code.com
|
102
|
+
executables: []
|
103
|
+
extensions:
|
104
|
+
- ext/extpp/extconf.rb
|
105
|
+
extra_rdoc_files: []
|
106
|
+
files:
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- doc/text/news.md
|
111
|
+
- ext/extpp/class.cpp
|
112
|
+
- ext/extpp/extconf.rb
|
113
|
+
- ext/extpp/function.cpp
|
114
|
+
- ext/extpp/object.cpp
|
115
|
+
- include/ruby.hpp
|
116
|
+
- include/ruby/cast.hpp
|
117
|
+
- include/ruby/class.hpp
|
118
|
+
- include/ruby/object.hpp
|
119
|
+
- include/ruby/type.hpp
|
120
|
+
- lib/extpp.rb
|
121
|
+
- lib/extpp/compiler.rb
|
122
|
+
- lib/extpp/version.rb
|
123
|
+
- test/fixtures/cast/cast.cpp
|
124
|
+
- test/fixtures/cast/extconf.rb
|
125
|
+
- test/fixtures/class/class.cpp
|
126
|
+
- test/fixtures/class/extconf.rb
|
127
|
+
- test/fixtures/object/extconf.rb
|
128
|
+
- test/fixtures/object/object.cpp
|
129
|
+
- test/helper.rb
|
130
|
+
- test/run-test.rb
|
131
|
+
- test/test-cast.rb
|
132
|
+
- test/test-class.rb
|
133
|
+
- test/test-object.rb
|
134
|
+
homepage: https://github.com/red-data-tools/extpp
|
135
|
+
licenses:
|
136
|
+
- BSD-2-Clause
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.5.2.2
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: Ext++ is a Ruby extension that provides C++ API for writing Ruby extension.
|
158
|
+
test_files:
|
159
|
+
- test/run-test.rb
|
160
|
+
- test/helper.rb
|
161
|
+
- test/test-object.rb
|
162
|
+
- test/test-class.rb
|
163
|
+
- test/test-cast.rb
|
164
|
+
- test/fixtures/object/object.cpp
|
165
|
+
- test/fixtures/object/extconf.rb
|
166
|
+
- test/fixtures/cast/extconf.rb
|
167
|
+
- test/fixtures/cast/cast.cpp
|
168
|
+
- test/fixtures/class/extconf.rb
|
169
|
+
- test/fixtures/class/class.cpp
|