rb_lovely 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6257def0a1d18050a37cfe61c6b6a07ebcc557b4
4
- data.tar.gz: 8500185c4d547bf45bd83ba3ecdc48dddae95ebb
3
+ metadata.gz: 2496d7e867af251fca88b09f09d803be15a9a0d5
4
+ data.tar.gz: 5f03cdfc07649d4f67fab1717086174b7d9499cc
5
5
  SHA512:
6
- metadata.gz: 8618d167887a777da7b37f2389555678528f3b5b919b44a39dec8686b0aa66805b3e9885c92f3f7cd3af075252125fd6f620d7777d3a4dae73ebf11d9ab5384e
7
- data.tar.gz: 411c88e8103e448542c8d39c8d5dbbcd9c5753529b21d2d021321bf4e8724da60276e9a9c53fa8b0be219285800d0455c111035b33960794fbe7d159083837a4
6
+ metadata.gz: b887607522f3a5e4afd85672cd6b085b5e6f791b741ca88f887057e381a42903d7ae06191b1130fe4449f80228ab7111b93f8d51e32c5ef06d7b094d924cbcb8
7
+ data.tar.gz: 73595cc2d2b79eda119ea76d2b2c9efdf44f781dee8915a1b7259885e56c19be2d5736ec0e7e489f2b2f60886da1b48ffed055e8b245444594b384475a483842
@@ -1,21 +1,10 @@
1
- #ifndef RB_LOVELY_SETS_SET_HPP
2
- #define RB_LOVELY_SETS_SET_HPP
1
+ #ifndef RB_LOVELY_SETS_CONTAINER_HPP
2
+ #define RB_LOVELY_SETS_CONTAINER_HPP
3
3
 
4
4
  #include "ruby_util.hpp"
5
5
 
6
6
  namespace rb_lovely {
7
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
8
  auto toS = [](VALUE val) { return RSTRING_PTR(rb_funcall(val, to_sSym, 0)); };
20
9
 
21
10
  }
@@ -7,6 +7,8 @@ namespace rb_lovely {
7
7
  VALUE equalitySym;
8
8
  VALUE to_sSym;
9
9
  VALUE hashSym;
10
+ VALUE compareSym;
11
+ VALUE callSym;
10
12
  }
11
13
 
12
14
  extern "C" {
@@ -9,6 +9,8 @@ extern VALUE cmpMethSym;
9
9
  extern VALUE equalitySym;
10
10
  extern VALUE to_sSym;
11
11
  extern VALUE hashSym;
12
+ extern VALUE callSym;
13
+ extern VALUE compareSym;
12
14
 
13
15
  template <class T>
14
16
  void rubyDelete(T *obj) {
@@ -33,6 +35,8 @@ static void initRubyUtil() {
33
35
  equalitySym = rb_intern("==");
34
36
  to_sSym = rb_intern("to_s");
35
37
  hashSym = rb_intern("hash");
38
+ callSym = rb_intern("call");
39
+ compareSym = ID2SYM(rb_intern("compare"));
36
40
  }
37
41
 
38
42
  }
@@ -12,8 +12,10 @@ namespace rb_lovely { namespace hybrid {
12
12
 
13
13
  struct member {
14
14
  bool operator<(member const& rhs) const {
15
- auto cmpVal = rb_funcall(val, cmpMethSym, 1, rhs.val);
16
- return NUM2INT(cmpVal) < 0;
15
+ auto cmpResult = compareProc != Qnil ?
16
+ rb_funcall(compareProc, callSym, 2, val, rhs.val) :
17
+ rb_funcall(val, cmpMethSym, 1, rhs.val);
18
+ return NUM2INT(cmpResult) < 0;
17
19
  }
18
20
 
19
21
  bool operator==(member const& rhs) const {
@@ -22,8 +24,10 @@ struct member {
22
24
  }
23
25
 
24
26
  // also cache as two element array?
25
- member(VALUE _key, VALUE _val) : key(_key), val(_val) {}
27
+ member(VALUE _compareProc, VALUE _key, VALUE _val)
28
+ : compareProc(_compareProc), key(_key), val(_val) {}
26
29
 
30
+ VALUE compareProc;
27
31
  VALUE key;
28
32
  VALUE val;
29
33
  };
@@ -36,19 +40,42 @@ std::size_t hash_value(member const& member) {
36
40
 
37
41
  namespace mi = boost::multi_index;
38
42
 
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;
43
+ struct Hash {
44
+ boost::multi_index_container<
45
+ member,
46
+ mi::indexed_by<
47
+ mi::hashed_unique< mi::member<member, VALUE, &member::key> >,
48
+ mi::ordered_non_unique< mi::identity<member> >
49
+ >
50
+ > container;
51
+
52
+ // proc used to compare values
53
+ VALUE compareProc = Qnil;
54
+ };
55
+
56
+ VALUE hashLength(VALUE self) {
57
+ Hash* hash = rubyCast<Hash>(self);
58
+ return INT2NUM(hash->container.size());
59
+ }
46
60
 
47
61
  VALUE hashInitialize(int argc, VALUE *argv, VALUE self) {
62
+ Hash* hash = rubyCast<Hash>(self);
48
63
  if (argc == 1) {
49
64
  auto array = rb_check_array_type(argv[0]);
50
65
  if (array == Qnil) {
51
- rb_raise(rb_eArgError, "Expected array");
66
+ auto kwArgs = rb_check_hash_type(argv[0]);
67
+ if (kwArgs == Qnil) {
68
+ rb_raise(rb_eArgError, "Expected array");
69
+ }
70
+ else {
71
+ auto compareProc = rb_hash_aref(kwArgs, compareSym);
72
+ if (compareProc == Qnil) {
73
+ rb_raise(rb_eArgError, "Expected compare keyword");
74
+ }
75
+ else {
76
+ hash->compareProc = compareProc;
77
+ }
78
+ }
52
79
  }
53
80
  else {
54
81
  auto len = RARRAY_LEN(array);
@@ -56,9 +83,8 @@ VALUE hashInitialize(int argc, VALUE *argv, VALUE self) {
56
83
  rb_raise(rb_eArgError, "Expected even number of parameters");
57
84
  }
58
85
  else {
59
- Hash* hash = rubyCast<Hash>(self);
60
86
  for (auto i = 0; i < len; i += 2) {
61
- hash->insert(member(rb_ary_entry(array, i), rb_ary_entry(array, i + 1)));
87
+ hash->container.insert(member(hash->compareProc, rb_ary_entry(array, i), rb_ary_entry(array, i + 1)));
62
88
  }
63
89
  }
64
90
  }
@@ -69,18 +95,18 @@ VALUE hashInitialize(int argc, VALUE *argv, VALUE self) {
69
95
  VALUE hashUpdate(VALUE self, VALUE key, VALUE val) {
70
96
  Hash* hash = rubyCast<Hash>(self);
71
97
  // TODO: overwrite value
72
- auto it = hash->find(key);
73
- if (it != hash->end())
74
- hash->replace(it, member(key, val));
98
+ auto it = hash->container.find(key);
99
+ if (it != hash->container.end())
100
+ hash->container.replace(it, member(hash->compareProc, key, val));
75
101
  else
76
- hash->insert(member(key, val));
102
+ hash->container.insert(member(hash->compareProc, key, val));
77
103
  return self;
78
104
  }
79
105
 
80
106
  VALUE hashGet(VALUE self, VALUE key) {
81
107
  Hash* hash = rubyCast<Hash>(self);
82
- auto it = hash->find(key);
83
- if (it == hash->end()) {
108
+ auto it = hash->container.find(key);
109
+ if (it == hash->container.end()) {
84
110
  return Qnil;
85
111
  }
86
112
  else {
@@ -95,7 +121,7 @@ VALUE hashEach(VALUE self) {
95
121
  }
96
122
  else {
97
123
  Hash* hash = rubyCast<Hash>(self);
98
- for (auto const& member : hash->get<1>()) {
124
+ for (auto const& member : hash->container.get<1>()) {
99
125
  rb_yield_values(2, member.key, member.val);
100
126
  }
101
127
  }
@@ -107,8 +133,8 @@ VALUE hashToString(VALUE self) {
107
133
  std::stringstream str;
108
134
  str << "RbLovely::SortedHash {";
109
135
  Hash* hash = rubyCast<Hash>(self);
110
- if (! hash->empty()) {
111
- auto& idx = hash->get<1>();
136
+ if (! hash->container.empty()) {
137
+ auto& idx = hash->container.get<1>();
112
138
  auto it = idx.begin();
113
139
  str << ' ' << toS(it->key) << " => " << toS(it->val);
114
140
  for (++it; it != idx.end(); ++it) {
@@ -123,38 +149,38 @@ VALUE hashToString(VALUE self) {
123
149
 
124
150
  VALUE hashFirst(VALUE self) {
125
151
  Hash* hash = rubyCast<Hash>(self);
126
- return hash->empty() ? Qnil : hash->get<1>().begin()->val;
152
+ return hash->container.empty() ? Qnil : hash->container.get<1>().begin()->val;
127
153
  }
128
154
 
129
155
  VALUE hashLast(VALUE self) {
130
156
  Hash* hash = rubyCast<Hash>(self);
131
- if (hash->empty())
157
+ if (hash->container.empty())
132
158
  return Qnil;
133
159
 
134
- auto last = hash->get<1>().end();
160
+ auto last = hash->container.get<1>().end();
135
161
  --last;
136
162
  return last->val;
137
163
  }
138
164
 
139
165
  VALUE hashMutatingDelete(VALUE self, VALUE toDelete) {
140
166
  Hash* hash = rubyCast<Hash>(self);
141
- auto it = hash->find(toDelete);
142
- if (it == hash->end()) {
167
+ auto it = hash->container.find(toDelete);
168
+ if (it == hash->container.end()) {
143
169
  return Qnil;
144
170
  }
145
171
  else {
146
172
  auto valBackup = it->val;
147
- hash->erase(it);
173
+ hash->container.erase(it);
148
174
  return valBackup;
149
175
  }
150
176
  }
151
177
 
152
178
  VALUE hashShift(VALUE self) {
153
179
  Hash* hash = rubyCast<Hash>(self);
154
- if (hash->empty())
180
+ if (hash->container.empty())
155
181
  return Qnil;
156
182
 
157
- auto& idx = hash->get<1>();
183
+ auto& idx = hash->container.get<1>();
158
184
  auto bak = idx.begin()->val;
159
185
  idx.erase(idx.begin());
160
186
  return bak;
@@ -162,10 +188,10 @@ VALUE hashShift(VALUE self) {
162
188
 
163
189
  VALUE hashPop(VALUE self) {
164
190
  Hash* hash = rubyCast<Hash>(self);
165
- if (hash->empty())
191
+ if (hash->container.empty())
166
192
  return Qnil;
167
193
 
168
- auto& idx = hash->get<1>();
194
+ auto& idx = hash->container.get<1>();
169
195
  auto last = idx.end();
170
196
  --last;
171
197
  auto bak = last->val;
@@ -175,8 +201,8 @@ VALUE hashPop(VALUE self) {
175
201
 
176
202
  VALUE hashHas(VALUE self, VALUE key) {
177
203
  Hash* hash = rubyCast<Hash>(self);
178
- auto it = hash->find(key);
179
- return it == hash->end() ? Qfalse : Qtrue;
204
+ auto it = hash->container.find(key);
205
+ return it == hash->container.end() ? Qfalse : Qtrue;
180
206
  }
181
207
 
182
208
  } }
@@ -191,7 +217,7 @@ extern "C" {
191
217
  rb_include_module(rbHash, rb_const_get(rb_cObject, rb_intern("Enumerable")));
192
218
 
193
219
  rb_define_method(rbHash, "initialize", RUBY_METHOD_FUNC(hashInitialize), -1);
194
- initSet<Hash>(rbHash);
220
+ rb_define_method(rbHash, "length", RUBY_METHOD_FUNC(hashLength), 0);
195
221
  rb_define_method(rbHash, "[]=", RUBY_METHOD_FUNC(hashUpdate), 2);
196
222
  rb_define_method(rbHash, "[]", RUBY_METHOD_FUNC(hashGet), 1);
197
223
  rb_define_method(rbHash, "each", RUBY_METHOD_FUNC(hashEach), 0);
@@ -35,6 +35,11 @@ VALUE setInitialize(int argc, VALUE *argv, VALUE self) {
35
35
  return self;
36
36
  }
37
37
 
38
+ VALUE setLength(VALUE self) {
39
+ Set* set = rubyCast<Set>(self);
40
+ return INT2NUM(set->size());
41
+ }
42
+
38
43
  VALUE setAdd(VALUE self, VALUE val) {
39
44
  Set* set = rubyCast<Set>(self);
40
45
  set->insert(val);
@@ -195,7 +200,7 @@ extern "C" {
195
200
  rb_include_module(rbSet, rb_const_get(rb_cObject, rb_intern("Enumerable")));
196
201
 
197
202
  rb_define_method(rbSet, "initialize", RUBY_METHOD_FUNC(setInitialize), -1);
198
- initSet<Set>(rbSet);
203
+ rb_define_method(rbSet, "length", RUBY_METHOD_FUNC(setLength), 0);
199
204
  rb_define_method(rbSet, "add", RUBY_METHOD_FUNC(setAdd), 1);
200
205
  rb_define_method(rbSet, "<<", RUBY_METHOD_FUNC(setAdd), 1);
201
206
  rb_define_method(rbSet, "each", RUBY_METHOD_FUNC(setEach), 0);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rb_lovely
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Pike