rb_lovely 0.3.3
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/ext/rb_lovely/container.hpp +22 -0
- data/ext/rb_lovely/extconf.rb +7 -0
- data/ext/rb_lovely/package.cpp +34 -0
- data/ext/rb_lovely/ruby_util.hpp +39 -0
- data/ext/rb_lovely/sorted_hash.cpp +212 -0
- data/ext/rb_lovely/sorted_set.cpp +214 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6257def0a1d18050a37cfe61c6b6a07ebcc557b4
|
4
|
+
data.tar.gz: 8500185c4d547bf45bd83ba3ecdc48dddae95ebb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8618d167887a777da7b37f2389555678528f3b5b919b44a39dec8686b0aa66805b3e9885c92f3f7cd3af075252125fd6f620d7777d3a4dae73ebf11d9ab5384e
|
7
|
+
data.tar.gz: 411c88e8103e448542c8d39c8d5dbbcd9c5753529b21d2d021321bf4e8724da60276e9a9c53fa8b0be219285800d0455c111035b33960794fbe7d159083837a4
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef RB_LOVELY_SETS_SET_HPP
|
2
|
+
#define RB_LOVELY_SETS_SET_HPP
|
3
|
+
|
4
|
+
#include "ruby_util.hpp"
|
5
|
+
|
6
|
+
namespace rb_lovely {
|
7
|
+
|
8
|
+
template <class T>
|
9
|
+
VALUE containerLength(VALUE self) {
|
10
|
+
T* set = rubyCast<T>(self);
|
11
|
+
return INT2NUM(set->size());
|
12
|
+
}
|
13
|
+
|
14
|
+
template <class T>
|
15
|
+
static void initSet(VALUE rbSet) {
|
16
|
+
rb_define_method(rbSet, "length", RUBY_METHOD_FUNC(containerLength<T>), 0);
|
17
|
+
}
|
18
|
+
|
19
|
+
auto toS = [](VALUE val) { return RSTRING_PTR(rb_funcall(val, to_sSym, 0)); };
|
20
|
+
|
21
|
+
}
|
22
|
+
#endif
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#include "ruby_util.hpp"
|
2
|
+
|
3
|
+
namespace rb_lovely {
|
4
|
+
// extern stuff from ruby_util
|
5
|
+
VALUE rbMod;
|
6
|
+
VALUE cmpMethSym;
|
7
|
+
VALUE equalitySym;
|
8
|
+
VALUE to_sSym;
|
9
|
+
VALUE hashSym;
|
10
|
+
}
|
11
|
+
|
12
|
+
extern "C" {
|
13
|
+
using namespace rb_lovely;
|
14
|
+
|
15
|
+
extern void Init_rb_lovely_sorted_set();
|
16
|
+
#ifdef HAVE_BOOST_MULTI_INDEX_CONTAINER_HPP
|
17
|
+
extern void Init_rb_lovely_hybrid_set();
|
18
|
+
#endif
|
19
|
+
|
20
|
+
void Init_rb_lovely() {
|
21
|
+
ruby_init();
|
22
|
+
ruby_init_loadpath();
|
23
|
+
|
24
|
+
initRubyUtil();
|
25
|
+
|
26
|
+
Init_rb_lovely_sorted_set();
|
27
|
+
#ifdef HAVE_BOOST_MULTI_INDEX_CONTAINER_HPP
|
28
|
+
Init_rb_lovely_hybrid_set();
|
29
|
+
#endif
|
30
|
+
|
31
|
+
// i saw this somewhere... but it dumps core... so um...
|
32
|
+
// ruby_finalize();
|
33
|
+
}
|
34
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#ifndef RB_LOVELY_SETS_UTIL_HPP
|
2
|
+
#define RB_LOVELY_SETS_UTIL_HPP
|
3
|
+
#include "ruby.h"
|
4
|
+
|
5
|
+
namespace rb_lovely {
|
6
|
+
|
7
|
+
extern VALUE rbMod;
|
8
|
+
extern VALUE cmpMethSym;
|
9
|
+
extern VALUE equalitySym;
|
10
|
+
extern VALUE to_sSym;
|
11
|
+
extern VALUE hashSym;
|
12
|
+
|
13
|
+
template <class T>
|
14
|
+
void rubyDelete(T *obj) {
|
15
|
+
delete obj;
|
16
|
+
}
|
17
|
+
|
18
|
+
template <class T>
|
19
|
+
T *rubyCast(VALUE rbObj) {
|
20
|
+
T *obj;
|
21
|
+
Data_Get_Struct(rbObj, T, obj);
|
22
|
+
return obj;
|
23
|
+
}
|
24
|
+
|
25
|
+
template <class T>
|
26
|
+
VALUE rubyAlloc(VALUE klass) {
|
27
|
+
return Data_Wrap_Struct(klass, 0, rubyDelete<T>, new T);
|
28
|
+
}
|
29
|
+
|
30
|
+
static void initRubyUtil() {
|
31
|
+
rbMod = rb_define_module("RbLovely");
|
32
|
+
cmpMethSym = rb_intern("<=>");
|
33
|
+
equalitySym = rb_intern("==");
|
34
|
+
to_sSym = rb_intern("to_s");
|
35
|
+
hashSym = rb_intern("hash");
|
36
|
+
}
|
37
|
+
|
38
|
+
}
|
39
|
+
#endif
|
@@ -0,0 +1,212 @@
|
|
1
|
+
#ifdef HAVE_BOOST_MULTI_INDEX_CONTAINER_HPP
|
2
|
+
#include "container.hpp"
|
3
|
+
|
4
|
+
#include "ruby_util.hpp"
|
5
|
+
|
6
|
+
#include <boost/multi_index_container.hpp>
|
7
|
+
#include <boost/multi_index/hashed_index.hpp>
|
8
|
+
#include <boost/multi_index/ordered_index.hpp>
|
9
|
+
#include <boost/multi_index/member.hpp>
|
10
|
+
|
11
|
+
namespace rb_lovely { namespace hybrid {
|
12
|
+
|
13
|
+
struct member {
|
14
|
+
bool operator<(member const& rhs) const {
|
15
|
+
auto cmpVal = rb_funcall(val, cmpMethSym, 1, rhs.val);
|
16
|
+
return NUM2INT(cmpVal) < 0;
|
17
|
+
}
|
18
|
+
|
19
|
+
bool operator==(member const& rhs) const {
|
20
|
+
auto equalityVal = rb_funcall(key, equalitySym, 1, rhs.key);
|
21
|
+
return RTEST(equalityVal);
|
22
|
+
}
|
23
|
+
|
24
|
+
// also cache as two element array?
|
25
|
+
member(VALUE _key, VALUE _val) : key(_key), val(_val) {}
|
26
|
+
|
27
|
+
VALUE key;
|
28
|
+
VALUE val;
|
29
|
+
};
|
30
|
+
|
31
|
+
std::size_t hash_value(member const& member) {
|
32
|
+
// TODO: something better?
|
33
|
+
return reinterpret_cast<std::size_t>(&member);
|
34
|
+
// return NUM2INT(rb_funcall(member.val, hashSym, 0));
|
35
|
+
}
|
36
|
+
|
37
|
+
namespace mi = boost::multi_index;
|
38
|
+
|
39
|
+
typedef boost::multi_index_container<
|
40
|
+
member,
|
41
|
+
mi::indexed_by<
|
42
|
+
mi::hashed_unique< mi::member<member, VALUE, &member::key> >,
|
43
|
+
mi::ordered_non_unique< mi::identity<member> >
|
44
|
+
>
|
45
|
+
> Hash;
|
46
|
+
|
47
|
+
VALUE hashInitialize(int argc, VALUE *argv, VALUE self) {
|
48
|
+
if (argc == 1) {
|
49
|
+
auto array = rb_check_array_type(argv[0]);
|
50
|
+
if (array == Qnil) {
|
51
|
+
rb_raise(rb_eArgError, "Expected array");
|
52
|
+
}
|
53
|
+
else {
|
54
|
+
auto len = RARRAY_LEN(array);
|
55
|
+
if (len % 2 != 0) {
|
56
|
+
rb_raise(rb_eArgError, "Expected even number of parameters");
|
57
|
+
}
|
58
|
+
else {
|
59
|
+
Hash* hash = rubyCast<Hash>(self);
|
60
|
+
for (auto i = 0; i < len; i += 2) {
|
61
|
+
hash->insert(member(rb_ary_entry(array, i), rb_ary_entry(array, i + 1)));
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
return self;
|
67
|
+
}
|
68
|
+
|
69
|
+
VALUE hashUpdate(VALUE self, VALUE key, VALUE val) {
|
70
|
+
Hash* hash = rubyCast<Hash>(self);
|
71
|
+
// TODO: overwrite value
|
72
|
+
auto it = hash->find(key);
|
73
|
+
if (it != hash->end())
|
74
|
+
hash->replace(it, member(key, val));
|
75
|
+
else
|
76
|
+
hash->insert(member(key, val));
|
77
|
+
return self;
|
78
|
+
}
|
79
|
+
|
80
|
+
VALUE hashGet(VALUE self, VALUE key) {
|
81
|
+
Hash* hash = rubyCast<Hash>(self);
|
82
|
+
auto it = hash->find(key);
|
83
|
+
if (it == hash->end()) {
|
84
|
+
return Qnil;
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
return it->val;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
VALUE hashEach(VALUE self) {
|
92
|
+
if (! rb_block_given_p()) {
|
93
|
+
// TODO: return Enumerator
|
94
|
+
rb_raise(rb_eArgError, "Expected block");
|
95
|
+
}
|
96
|
+
else {
|
97
|
+
Hash* hash = rubyCast<Hash>(self);
|
98
|
+
for (auto const& member : hash->get<1>()) {
|
99
|
+
rb_yield_values(2, member.key, member.val);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
return Qnil;
|
104
|
+
}
|
105
|
+
|
106
|
+
VALUE hashToString(VALUE self) {
|
107
|
+
std::stringstream str;
|
108
|
+
str << "RbLovely::SortedHash {";
|
109
|
+
Hash* hash = rubyCast<Hash>(self);
|
110
|
+
if (! hash->empty()) {
|
111
|
+
auto& idx = hash->get<1>();
|
112
|
+
auto it = idx.begin();
|
113
|
+
str << ' ' << toS(it->key) << " => " << toS(it->val);
|
114
|
+
for (++it; it != idx.end(); ++it) {
|
115
|
+
str << ", " << toS(it->key) << " => " << toS(it->val);
|
116
|
+
}
|
117
|
+
}
|
118
|
+
str << " }";
|
119
|
+
|
120
|
+
auto stlString = str.str();
|
121
|
+
return rb_str_new(stlString.data(), stlString.size());
|
122
|
+
}
|
123
|
+
|
124
|
+
VALUE hashFirst(VALUE self) {
|
125
|
+
Hash* hash = rubyCast<Hash>(self);
|
126
|
+
return hash->empty() ? Qnil : hash->get<1>().begin()->val;
|
127
|
+
}
|
128
|
+
|
129
|
+
VALUE hashLast(VALUE self) {
|
130
|
+
Hash* hash = rubyCast<Hash>(self);
|
131
|
+
if (hash->empty())
|
132
|
+
return Qnil;
|
133
|
+
|
134
|
+
auto last = hash->get<1>().end();
|
135
|
+
--last;
|
136
|
+
return last->val;
|
137
|
+
}
|
138
|
+
|
139
|
+
VALUE hashMutatingDelete(VALUE self, VALUE toDelete) {
|
140
|
+
Hash* hash = rubyCast<Hash>(self);
|
141
|
+
auto it = hash->find(toDelete);
|
142
|
+
if (it == hash->end()) {
|
143
|
+
return Qnil;
|
144
|
+
}
|
145
|
+
else {
|
146
|
+
auto valBackup = it->val;
|
147
|
+
hash->erase(it);
|
148
|
+
return valBackup;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
VALUE hashShift(VALUE self) {
|
153
|
+
Hash* hash = rubyCast<Hash>(self);
|
154
|
+
if (hash->empty())
|
155
|
+
return Qnil;
|
156
|
+
|
157
|
+
auto& idx = hash->get<1>();
|
158
|
+
auto bak = idx.begin()->val;
|
159
|
+
idx.erase(idx.begin());
|
160
|
+
return bak;
|
161
|
+
}
|
162
|
+
|
163
|
+
VALUE hashPop(VALUE self) {
|
164
|
+
Hash* hash = rubyCast<Hash>(self);
|
165
|
+
if (hash->empty())
|
166
|
+
return Qnil;
|
167
|
+
|
168
|
+
auto& idx = hash->get<1>();
|
169
|
+
auto last = idx.end();
|
170
|
+
--last;
|
171
|
+
auto bak = last->val;
|
172
|
+
idx.erase(last);
|
173
|
+
return bak;
|
174
|
+
}
|
175
|
+
|
176
|
+
VALUE hashHas(VALUE self, VALUE key) {
|
177
|
+
Hash* hash = rubyCast<Hash>(self);
|
178
|
+
auto it = hash->find(key);
|
179
|
+
return it == hash->end() ? Qfalse : Qtrue;
|
180
|
+
}
|
181
|
+
|
182
|
+
} }
|
183
|
+
|
184
|
+
extern "C" {
|
185
|
+
using namespace rb_lovely;
|
186
|
+
using namespace rb_lovely::hybrid;
|
187
|
+
|
188
|
+
void Init_rb_lovely_hybrid_set() {
|
189
|
+
auto rbHash = rb_define_class_under(rbMod, "SortedHash", rb_cObject);
|
190
|
+
rb_define_alloc_func(rbHash, rubyAlloc<Hash>);
|
191
|
+
rb_include_module(rbHash, rb_const_get(rb_cObject, rb_intern("Enumerable")));
|
192
|
+
|
193
|
+
rb_define_method(rbHash, "initialize", RUBY_METHOD_FUNC(hashInitialize), -1);
|
194
|
+
initSet<Hash>(rbHash);
|
195
|
+
rb_define_method(rbHash, "[]=", RUBY_METHOD_FUNC(hashUpdate), 2);
|
196
|
+
rb_define_method(rbHash, "[]", RUBY_METHOD_FUNC(hashGet), 1);
|
197
|
+
rb_define_method(rbHash, "each", RUBY_METHOD_FUNC(hashEach), 0);
|
198
|
+
rb_define_method(rbHash, "to_s", RUBY_METHOD_FUNC(hashToString), 0);
|
199
|
+
rb_define_method(rbHash, "first", RUBY_METHOD_FUNC(hashFirst), 0);
|
200
|
+
rb_define_method(rbHash, "last", RUBY_METHOD_FUNC(hashLast), 0);
|
201
|
+
rb_define_method(rbHash, "delete", RUBY_METHOD_FUNC(hashMutatingDelete), 1);
|
202
|
+
// rb_define_method(rbHash, "reject!", RUBY_METHOD_FUNC(hashMutatingReject), 0);
|
203
|
+
// rb_define_method(rbHash, "reject_first!", RUBY_METHOD_FUNC(hashMutatingRejectFirst), 0);
|
204
|
+
// rb_define_method(rbHash, "select!", RUBY_METHOD_FUNC(hashMutatingSelect), 0);
|
205
|
+
rb_define_method(rbHash, "shift", RUBY_METHOD_FUNC(hashShift), 0);
|
206
|
+
rb_define_method(rbHash, "pop", RUBY_METHOD_FUNC(hashPop), 0);
|
207
|
+
// Enumerable would test both key and value for include?
|
208
|
+
rb_define_method(rbHash, "include?", RUBY_METHOD_FUNC(hashHas), 1);
|
209
|
+
rb_define_method(rbHash, "has_key?", RUBY_METHOD_FUNC(hashHas), 1);
|
210
|
+
}
|
211
|
+
}
|
212
|
+
#endif
|
@@ -0,0 +1,214 @@
|
|
1
|
+
#include "container.hpp"
|
2
|
+
|
3
|
+
#include "ruby_util.hpp"
|
4
|
+
|
5
|
+
#include <set>
|
6
|
+
#include <sstream>
|
7
|
+
|
8
|
+
namespace rb_lovely { namespace ordered {
|
9
|
+
|
10
|
+
struct Compare {
|
11
|
+
bool operator()(VALUE const& lhs, VALUE const& rhs);
|
12
|
+
};
|
13
|
+
|
14
|
+
typedef std::set<VALUE, Compare> Set;
|
15
|
+
|
16
|
+
bool Compare::operator()(VALUE const& lhs, VALUE const& rhs) {
|
17
|
+
auto cmpVal = rb_funcall(lhs, cmpMethSym, 1, rhs);
|
18
|
+
return NUM2INT(cmpVal) < 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
VALUE setInitialize(int argc, VALUE *argv, VALUE self) {
|
22
|
+
if (argc == 1) {
|
23
|
+
auto array = rb_check_array_type(argv[0]);
|
24
|
+
if (array == Qnil) {
|
25
|
+
rb_raise(rb_eArgError, "Expected array");
|
26
|
+
}
|
27
|
+
else {
|
28
|
+
Set* set = rubyCast<Set>(self);
|
29
|
+
auto len = RARRAY_LEN(array);
|
30
|
+
for (auto i = 0; i < len; ++i) {
|
31
|
+
set->insert(rb_ary_entry(array, i));
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
return self;
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE setAdd(VALUE self, VALUE val) {
|
39
|
+
Set* set = rubyCast<Set>(self);
|
40
|
+
set->insert(val);
|
41
|
+
return self;
|
42
|
+
}
|
43
|
+
|
44
|
+
VALUE setEach(VALUE self) {
|
45
|
+
if (! rb_block_given_p()) {
|
46
|
+
// TODO: return Enumerator
|
47
|
+
rb_raise(rb_eArgError, "Expected block");
|
48
|
+
}
|
49
|
+
else {
|
50
|
+
Set* set = rubyCast<Set>(self);
|
51
|
+
for (auto const& val : *set) {
|
52
|
+
rb_yield(val);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
return Qnil;
|
57
|
+
}
|
58
|
+
|
59
|
+
VALUE setToString(VALUE self) {
|
60
|
+
std::stringstream str;
|
61
|
+
str << "RbLovely::SortedSet {";
|
62
|
+
Set* set = rubyCast<Set>(self);
|
63
|
+
if (! set->empty()) {
|
64
|
+
auto it = set->begin();
|
65
|
+
str << ' ' << toS(*it);
|
66
|
+
for (++it; it != set->end(); ++it) {
|
67
|
+
str << ", " << toS(*it);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
str << " }";
|
71
|
+
|
72
|
+
auto stlString = str.str();
|
73
|
+
return rb_str_new(stlString.data(), stlString.size());
|
74
|
+
}
|
75
|
+
|
76
|
+
VALUE setFirst(VALUE self) {
|
77
|
+
Set* set = rubyCast<Set>(self);
|
78
|
+
|
79
|
+
return set->empty() ? Qnil : *set->begin();
|
80
|
+
}
|
81
|
+
|
82
|
+
VALUE setLast(VALUE self) {
|
83
|
+
Set* set = rubyCast<Set>(self);
|
84
|
+
if (set->empty())
|
85
|
+
return Qnil;
|
86
|
+
|
87
|
+
auto last = set->end();
|
88
|
+
--last;
|
89
|
+
return *last;
|
90
|
+
}
|
91
|
+
|
92
|
+
VALUE setMutatingDelete(VALUE self, VALUE toDelete) {
|
93
|
+
Set* set = rubyCast<Set>(self);
|
94
|
+
auto it = set->find(toDelete);
|
95
|
+
if (it == set->end()) {
|
96
|
+
return Qnil;
|
97
|
+
}
|
98
|
+
else {
|
99
|
+
auto valBackup = *it;
|
100
|
+
set->erase(it);
|
101
|
+
return valBackup;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
VALUE setMutatingReject(VALUE self) {
|
106
|
+
if (! rb_block_given_p()) {
|
107
|
+
rb_raise(rb_eArgError, "Expected block");
|
108
|
+
}
|
109
|
+
else {
|
110
|
+
Set* set = rubyCast<Set>(self);
|
111
|
+
for (auto it = set->begin(); it != set->end();) {
|
112
|
+
auto predicateRetVal = rb_yield(*it);
|
113
|
+
if (RTEST(predicateRetVal))
|
114
|
+
it = set->erase(it);
|
115
|
+
else
|
116
|
+
++it;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
return self;
|
120
|
+
}
|
121
|
+
|
122
|
+
VALUE setMutatingRejectFirst(VALUE self) {
|
123
|
+
if (! rb_block_given_p()) {
|
124
|
+
rb_raise(rb_eArgError, "Expected block");
|
125
|
+
}
|
126
|
+
else {
|
127
|
+
Set* set = rubyCast<Set>(self);
|
128
|
+
for (auto it = set->begin(); it != set->end(); ++it) {
|
129
|
+
auto predicateRetVal = rb_yield(*it);
|
130
|
+
if (RTEST(predicateRetVal)) {
|
131
|
+
auto valBackup = *it;
|
132
|
+
set->erase(it);
|
133
|
+
return valBackup;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
return Qnil;
|
138
|
+
}
|
139
|
+
|
140
|
+
VALUE setMutatingSelect(VALUE self) {
|
141
|
+
if (! rb_block_given_p()) {
|
142
|
+
rb_raise(rb_eArgError, "Expected block");
|
143
|
+
return self;
|
144
|
+
}
|
145
|
+
else {
|
146
|
+
Set* set = rubyCast<Set>(self);
|
147
|
+
for (auto it = set->begin(); it != set->end();) {
|
148
|
+
auto predicateRetVal = rb_yield(*it);
|
149
|
+
if (! RTEST(predicateRetVal))
|
150
|
+
it = set->erase(it);
|
151
|
+
else
|
152
|
+
++it;
|
153
|
+
}
|
154
|
+
}
|
155
|
+
return self;
|
156
|
+
}
|
157
|
+
|
158
|
+
VALUE setShift(VALUE self) {
|
159
|
+
Set* set = rubyCast<Set>(self);
|
160
|
+
if (set->empty())
|
161
|
+
return Qnil;
|
162
|
+
|
163
|
+
auto bak = *set->begin();
|
164
|
+
set->erase(set->begin());
|
165
|
+
return bak;
|
166
|
+
}
|
167
|
+
|
168
|
+
VALUE setPop(VALUE self) {
|
169
|
+
Set* set = rubyCast<Set>(self);
|
170
|
+
if (set->empty())
|
171
|
+
return Qnil;
|
172
|
+
|
173
|
+
auto last = set->end();
|
174
|
+
--last;
|
175
|
+
auto bak = *last;
|
176
|
+
set->erase(last);
|
177
|
+
return bak;
|
178
|
+
}
|
179
|
+
|
180
|
+
VALUE setHas(VALUE self, VALUE val) {
|
181
|
+
Set* set = rubyCast<Set>(self);
|
182
|
+
auto it = set->find(val);
|
183
|
+
return it == set->end() ? Qfalse : Qtrue;
|
184
|
+
}
|
185
|
+
|
186
|
+
} } // end namespace
|
187
|
+
|
188
|
+
extern "C" {
|
189
|
+
using namespace rb_lovely;
|
190
|
+
using namespace rb_lovely::ordered;
|
191
|
+
|
192
|
+
void Init_rb_lovely_sorted_set() {
|
193
|
+
auto rbSet = rb_define_class_under(rbMod, "SortedSet", rb_cObject);
|
194
|
+
rb_define_alloc_func(rbSet, rubyAlloc<Set>);
|
195
|
+
rb_include_module(rbSet, rb_const_get(rb_cObject, rb_intern("Enumerable")));
|
196
|
+
|
197
|
+
rb_define_method(rbSet, "initialize", RUBY_METHOD_FUNC(setInitialize), -1);
|
198
|
+
initSet<Set>(rbSet);
|
199
|
+
rb_define_method(rbSet, "add", RUBY_METHOD_FUNC(setAdd), 1);
|
200
|
+
rb_define_method(rbSet, "<<", RUBY_METHOD_FUNC(setAdd), 1);
|
201
|
+
rb_define_method(rbSet, "each", RUBY_METHOD_FUNC(setEach), 0);
|
202
|
+
rb_define_method(rbSet, "to_s", RUBY_METHOD_FUNC(setToString), 0);
|
203
|
+
rb_define_method(rbSet, "first", RUBY_METHOD_FUNC(setFirst), 0);
|
204
|
+
rb_define_method(rbSet, "last", RUBY_METHOD_FUNC(setLast), 0);
|
205
|
+
rb_define_method(rbSet, "delete", RUBY_METHOD_FUNC(setMutatingDelete), 1);
|
206
|
+
rb_define_method(rbSet, "reject!", RUBY_METHOD_FUNC(setMutatingReject), 0);
|
207
|
+
rb_define_method(rbSet, "reject_first!", RUBY_METHOD_FUNC(setMutatingRejectFirst), 0);
|
208
|
+
rb_define_method(rbSet, "select!", RUBY_METHOD_FUNC(setMutatingSelect), 0);
|
209
|
+
rb_define_method(rbSet, "shift", RUBY_METHOD_FUNC(setShift), 0);
|
210
|
+
rb_define_method(rbSet, "pop", RUBY_METHOD_FUNC(setPop), 0);
|
211
|
+
// Enumerable provides a slower version of this
|
212
|
+
rb_define_method(rbSet, "include?", RUBY_METHOD_FUNC(setHas), 1);
|
213
|
+
}
|
214
|
+
}
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rb_lovely
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Pike
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-01 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A fast sorted set built using std::set and a fast sorted hash built using
|
14
|
+
boost::multi_index_container.
|
15
|
+
email:
|
16
|
+
- gems@chilon.net
|
17
|
+
executables: []
|
18
|
+
extensions:
|
19
|
+
- ext/rb_lovely/extconf.rb
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- ext/rb_lovely/container.hpp
|
23
|
+
- ext/rb_lovely/extconf.rb
|
24
|
+
- ext/rb_lovely/package.cpp
|
25
|
+
- ext/rb_lovely/ruby_util.hpp
|
26
|
+
- ext/rb_lovely/sorted_hash.cpp
|
27
|
+
- ext/rb_lovely/sorted_set.cpp
|
28
|
+
homepage: https://github.com/nuisanceofcats/rb_lovely
|
29
|
+
licenses:
|
30
|
+
- Expat
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.2.2
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: Fast sorted sets and hashes.
|
52
|
+
test_files: []
|