s_matrix 1.0.1 → 1.0.2

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: 873b7c7f5cf89a315b84cd9b373923819962522c
4
- data.tar.gz: 9706ed9b6207ddeba5970c09ba027c6bc0739b62
3
+ metadata.gz: d0a1d9986c5eee4c83153245c8ecb30da21d3609
4
+ data.tar.gz: 8cd70ce3cf6a73ac9acb964b3bb7483979c1686e
5
5
  SHA512:
6
- metadata.gz: 5015507f5e37081199965b0098dc2ee9d0f6e4df0bab055c55d159bbb1127b6e9295e36350586634980d140ab80adcfdc3906a7a8b33aff6f4156bec27518793
7
- data.tar.gz: c16ea95270874368b5c53f531f455d1c2abef4e3412c335860a8b3b2e8c754be8187694b3eb20d5778335b55dc59b7e9b10f0533a0ee00a660f420486fa2712e
6
+ metadata.gz: 6840c3d37d7b86ebb9c2034a7cf295587daff1ac5be8273a2c8bf3eabf33593b0ab334807c9dc3bfaa8dfec2817d312ec017371e15f93bf8f77e728dc678ce52
7
+ data.tar.gz: 2b33b8b9209bf4c262ea642684bc2332d326e30fc0cecedf5b72c56b10d6958b52f280a0df37cf22862fdbb971244922e4262ac216ae2a6e671e777add55bdb9
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- Current version 1.0.0
2
- Latest stable version is 1.0.0
1
+ Current version 1.0.2
3
2
 
4
3
  ### Matrix reduce memory usage for large Hash.
5
4
  Matrix store the hash like this: <br>
@@ -46,16 +45,21 @@ Or install it yourself as:
46
45
  EQUIPMENTS.size.should == 2
47
46
  # or you can use get\_row instead of []<br>
48
47
  EQUIPMENTS.get\_row('20002')<br>
49
- # each
50
- EQUIPMENTS.each {|k, v| k == '10001', v == {'id' => '10001', 'name' => 'sword', ...} }
51
- # all
52
- EQUIPMENTS.all.should == { '20002' => {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}, '20003' => {} }
53
- # ids
54
- EQUIPMENTS.ids.should == ['20002', '20003']
55
- # keys
56
- EQUIPMENTS.keys.should == ['id', 'name', 'hp']
57
- # to\_s for debug
58
- puts EQUIPMENTS.to_s
48
+ # each<br>
49
+ EQUIPMENTS.each {|k, v| k == '10001', v == {'id' => '10001', 'name' => 'sword', ...} }<br>
50
+ # all<br>
51
+ EQUIPMENTS.all.should == { '20002' => {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}, '20003' => {} }<br>
52
+ # first<br>
53
+ EQUIPMENTS.first.should == ['20002', {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}]
54
+ # ids<br>
55
+ EQUIPMENTS.ids.should == ['20002', '20003']<br>
56
+ # keys<br>
57
+ EQUIPMENTS.keys.should == ['id', 'name', 'hp']<br>
58
+ # find -- find the first one<br>
59
+ EQUIPMENTS.find({name: 'shoe'}).should == ['20002', {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}]
60
+ # to\_s for debug<br>
61
+ puts EQUIPMENTS.to_s<br>
62
+
59
63
 
60
64
  ### todolist
61
65
  https://github.com/libinzhangyuan/s\_matrix/blob/master/todolist.txt
@@ -5,6 +5,8 @@
5
5
  #include "stdio.h"
6
6
 
7
7
 
8
+ bool GMatx::t_continue = true;
9
+ bool GMatx::t_break = false;
8
10
  GMatx::GMatx(void)
9
11
  {
10
12
  }
@@ -43,7 +45,6 @@ const std::vector<std::string>& GMatx::get_titles(void) const
43
45
  return m_titles.get_titles();
44
46
  }
45
47
 
46
- // typedef void (*each_call_func)(const std::string& /*key*/, const t_key_value_hash& /*row_content*/, void* args);
47
48
  void GMatx::each_call(each_call_func func, void* args) const
48
49
  {
49
50
  const std::vector<std::string>& titles = m_titles.get_titles();
@@ -52,7 +53,8 @@ void GMatx::each_call(each_call_func func, void* args) const
52
53
  {
53
54
  const std::string& id = iter->first;
54
55
  const MatxRow& row = iter->second;
55
- func(id, row.to_key_value_hash(titles), args);
56
+ if (func(id, row.to_key_value_hash(titles), args) == GMatx::t_break)
57
+ break;
56
58
  }
57
59
  }
58
60
 
@@ -70,3 +72,19 @@ size_t GMatx::size(void) const
70
72
  {
71
73
  return m_contents.size();
72
74
  }
75
+
76
+ t_key_value_hash GMatx::first(std::string& id_out) const
77
+ {
78
+ t_key_value_hash result;
79
+
80
+ // empty matx.
81
+ //
82
+ std::map<std::string /* id */, MatxRow>::const_iterator iter = m_contents.begin();
83
+ if (iter == m_contents.end())
84
+ return result;
85
+
86
+ id_out = iter->first;
87
+ const MatxRow& row = iter->second;
88
+ const std::vector<std::string>& titles = m_titles.get_titles();
89
+ return row.to_key_value_hash(titles);
90
+ }
data/ext/s_matrix/gmatx.h CHANGED
@@ -19,9 +19,14 @@ public:
19
19
  std::string to_s(void) const;
20
20
  size_t size(void) const;
21
21
 
22
+ t_key_value_hash first(std::string& id_out) const;
23
+
22
24
  // iterator function
23
25
  // the args parameter of each_call function will pass to callback function each_call_func.
24
- typedef void (*each_call_func)(const std::string& /*key*/, const t_key_value_hash& /*row_content*/, void* args);
26
+ // the return of each_call_func indicate continue iterator or not. - true means continue. false means break.
27
+ static bool t_continue;
28
+ static bool t_break;
29
+ typedef bool (*each_call_func)(const std::string& /*id*/, const t_key_value_hash& /*row_content*/, void* args);
25
30
  void each_call(each_call_func func, void* args) const;
26
31
 
27
32
  private:
@@ -0,0 +1,62 @@
1
+ #include <sstream>
2
+
3
+ #include "matx_hash_util.h"
4
+ #include "stdio.h"
5
+ #include "matx_row.h"
6
+
7
+ namespace MatxHashUtil
8
+ {
9
+
10
+ VALUE key_value_hash_to_ruby_hash(const t_key_value_hash& row_hash)
11
+ {
12
+ VALUE ret_hash = rb_hash_new();
13
+ for (t_key_value_hash::const_iterator iter = row_hash.begin(); iter != row_hash.end(); ++iter)
14
+ {
15
+ const std::string& key = iter->first;
16
+ const std::string& value = iter->second;
17
+ if (value == MatxRow::null_string)
18
+ rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), Qnil);
19
+ else
20
+ rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), rb_str_new_cstr(value.c_str()));
21
+ }
22
+ return ret_hash;
23
+ }
24
+
25
+ int hash_iter_func(VALUE key, VALUE value, VALUE p_row_hash)
26
+ {
27
+ t_key_value_hash* p_hash = (t_key_value_hash*)p_row_hash;
28
+
29
+ // key
30
+ VALUE key_str = rb_funcall(key, rb_intern("to_s"), 0);
31
+
32
+ // value
33
+ std::string str_value;
34
+ if (TYPE(value) == T_NIL)
35
+ str_value = MatxRow::null_string;
36
+ else
37
+ {
38
+ VALUE rb_str = rb_funcall(value, rb_intern("to_s"), 0);
39
+ str_value = StringValueCStr( rb_str );
40
+ }
41
+
42
+ (*p_hash)[StringValueCStr(key_str)] = str_value;
43
+ return ST_CONTINUE;
44
+ }
45
+
46
+ t_key_value_hash rb_hash_to_key_value_hash(VALUE rb_hash)
47
+ {
48
+ t_key_value_hash row_hash;
49
+ rb_hash_foreach(rb_hash, (int (*)(ANYARGS))hash_iter_func, (VALUE)&row_hash);
50
+ return row_hash;
51
+ }
52
+
53
+ std::string key_value_hash_to_str(const t_key_value_hash& row_hash)
54
+ {
55
+ std::ostringstream ostr;
56
+ ostr << "--row_hash: size = " << row_hash.size() << std::endl;
57
+ for (t_key_value_hash::const_iterator iter = row_hash.begin(); iter!= row_hash.end(); ++iter)
58
+ ostr << iter->first << " -> " << iter->second << std::endl;
59
+ ostr << std::endl;
60
+ return ostr.str();
61
+ }
62
+ }
@@ -0,0 +1,20 @@
1
+ #ifndef _MATX_HASH_UTIL_H_
2
+ #define _MATX_HASH_UTIL_H_
3
+
4
+ #include <string>
5
+ #include <map>
6
+ #include "matx_type_def.h"
7
+
8
+ #include "ruby.h"
9
+
10
+ namespace MatxHashUtil
11
+ {
12
+ VALUE key_value_hash_to_ruby_hash(const t_key_value_hash& row_hash);
13
+ t_key_value_hash rb_hash_to_key_value_hash(VALUE rb_hash);
14
+
15
+ std::string key_value_hash_to_str(const t_key_value_hash& row_hash);
16
+ }
17
+
18
+
19
+
20
+ #endif // _MATX_HASH_UTIL_H_
@@ -4,6 +4,7 @@
4
4
  #include "ruby/util.h"
5
5
 
6
6
  #include "gmatx.h"
7
+ #include "matx_hash_util.h"
7
8
 
8
9
  static VALUE t_init(VALUE self);
9
10
  static VALUE t_init_copy(VALUE self, VALUE orig);
@@ -51,19 +52,6 @@ static VALUE sm_alloc(VALUE klass)
51
52
  return Data_Wrap_Struct(klass, 0, free_matx, pMatx);
52
53
  }
53
54
 
54
- static int t_add_row_hash_iter_func(VALUE key, VALUE value, VALUE p_row_hash)
55
- {
56
- t_key_value_hash* p_hash = (t_key_value_hash*)p_row_hash;
57
-
58
- VALUE key_str = rb_funcall(key, rb_intern("to_s"), 0);
59
- VALUE value_str = rb_funcall(value, rb_intern("to_s"), 0);
60
- //printf("key: %s, value: %s, p_hash size %lu\n", StringValueCStr(key_str), StringValueCStr(value_str), p_hash->size());
61
-
62
- (*p_hash)[StringValueCStr(key_str)] = StringValueCStr(value_str);
63
- return ST_CONTINUE;
64
- }
65
-
66
-
67
55
  // row: {hp: 23, name: '2332342', 'text' => 'fsdfsd'}
68
56
  static VALUE t_add_row(VALUE self, VALUE id, VALUE row)
69
57
  {
@@ -80,8 +68,7 @@ static VALUE t_add_row(VALUE self, VALUE id, VALUE row)
80
68
 
81
69
  // 处理row deal with row
82
70
  //
83
- t_key_value_hash row_hash;
84
- rb_hash_foreach(row, (int (*)(ANYARGS))t_add_row_hash_iter_func, (VALUE)&row_hash);
71
+ const t_key_value_hash& row_hash = MatxHashUtil::rb_hash_to_key_value_hash(row);
85
72
 
86
73
  // 存数据 store data
87
74
  //
@@ -93,21 +80,6 @@ static VALUE t_add_row(VALUE self, VALUE id, VALUE row)
93
80
  return self;
94
81
  }
95
82
 
96
- static VALUE row_hash_to_ruby_hash(const t_key_value_hash& row_hash)
97
- {
98
- VALUE ret_hash = rb_hash_new();
99
- for (t_key_value_hash::const_iterator iter = row_hash.begin(); iter != row_hash.end(); ++iter)
100
- {
101
- const std::string& key = iter->first;
102
- const std::string& value = iter->second;
103
- if (value == MatxRow::null_string)
104
- rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), Qnil);
105
- else
106
- rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), rb_str_new_cstr(value.c_str()));
107
- }
108
- return ret_hash;
109
- }
110
-
111
83
  static VALUE t_get_row(VALUE self, VALUE id)
112
84
  {
113
85
  // 处理id deal with id
@@ -123,12 +95,69 @@ static VALUE t_get_row(VALUE self, VALUE id)
123
95
  Data_Get_Struct(self, class GMatx, pMatx);
124
96
 
125
97
  t_key_value_hash row_hash = pMatx->get_row(std::string(p_id_c_str));
126
- return row_hash_to_ruby_hash(row_hash);
98
+ return MatxHashUtil::key_value_hash_to_ruby_hash(row_hash);
99
+ }
100
+
101
+ struct FindCallbackArgs
102
+ {
103
+ std::string id;
104
+ t_key_value_hash row_content;
105
+
106
+ t_key_value_hash search_keys;
107
+ };
108
+ static bool callback_func__find(const std::string& id, const t_key_value_hash& row_content, void* args)
109
+ {
110
+ FindCallbackArgs* pargs = (FindCallbackArgs*)(args);
111
+ for (t_key_value_hash::const_iterator iter = pargs->search_keys.begin();
112
+ iter != pargs->search_keys.end(); ++iter)
113
+ {
114
+ const std::string& search_key = iter->first;
115
+ const std::string& search_value = iter->second;
116
+
117
+ t_key_value_hash::const_iterator row_content_iter = row_content.find(search_key);
118
+
119
+ // compare nil value. -- s.find({a: '3', b: nil}) when compile b: nil
120
+ if (search_value == MatxRow::null_string)
121
+ {
122
+ if (row_content_iter != row_content.end() && row_content_iter->second != search_value)
123
+ return GMatx::t_continue;
124
+ continue;
125
+ }
126
+
127
+ // compare value not nil
128
+ if (row_content_iter == row_content.end() || row_content_iter->second != search_value)
129
+ return GMatx::t_continue;
130
+ }
131
+ pargs->id = id;
132
+ pargs->row_content = row_content;
133
+ return GMatx::t_break;
127
134
  }
128
135
 
129
- static void callback_func__each(const std::string& key, const t_key_value_hash& row_content, void* args)
136
+ static VALUE t_find(VALUE self, VALUE search_keys_ruby_hash)
130
137
  {
131
- rb_yield_values(2, rb_str_new_cstr(key.c_str()), row_hash_to_ruby_hash(row_content));
138
+ Check_Type(search_keys_ruby_hash, T_HASH);
139
+
140
+ struct FindCallbackArgs args;
141
+ args.search_keys = MatxHashUtil::rb_hash_to_key_value_hash(search_keys_ruby_hash);
142
+
143
+ class GMatx* pMatx = NULL;
144
+ Data_Get_Struct(self, class GMatx, pMatx);
145
+ pMatx->each_call(callback_func__find, &args);
146
+ if (args.id.size() > 0)
147
+ {
148
+ VALUE ret_ary = rb_ary_new();
149
+ rb_ary_push(ret_ary, rb_str_new_cstr(args.id.c_str()));
150
+ rb_ary_push(ret_ary, MatxHashUtil::key_value_hash_to_ruby_hash(args.row_content));
151
+ return ret_ary;
152
+ }
153
+ return Qnil;
154
+ }
155
+
156
+
157
+ static bool callback_func__each(const std::string& key, const t_key_value_hash& row_content, void* args)
158
+ {
159
+ rb_yield_values(2, rb_str_new_cstr(key.c_str()), MatxHashUtil::key_value_hash_to_ruby_hash(row_content));
160
+ return GMatx::t_continue;
132
161
  }
133
162
 
134
163
  static VALUE t_each(VALUE self)
@@ -144,10 +173,11 @@ static VALUE t_each(VALUE self)
144
173
  return self;
145
174
  }
146
175
 
147
- static void callback_func__all(const std::string& key, const t_key_value_hash& row_content, void* args)
176
+ static bool callback_func__all(const std::string& key, const t_key_value_hash& row_content, void* args)
148
177
  {
149
178
  VALUE* p_ret_hash = (VALUE*)(args);
150
- rb_hash_aset(*p_ret_hash, rb_str_new_cstr(key.c_str()), row_hash_to_ruby_hash(row_content));
179
+ rb_hash_aset(*p_ret_hash, rb_str_new_cstr(key.c_str()), MatxHashUtil::key_value_hash_to_ruby_hash(row_content));
180
+ return GMatx::t_continue;
151
181
  }
152
182
 
153
183
  static VALUE t_all(VALUE self)
@@ -160,10 +190,11 @@ static VALUE t_all(VALUE self)
160
190
  return ret_hash;
161
191
  }
162
192
 
163
- static void callback_func__ids(const std::string& key, const t_key_value_hash& row_content, void* args)
193
+ static bool callback_func__ids(const std::string& key, const t_key_value_hash& row_content, void* args)
164
194
  {
165
195
  VALUE* p_ret_array = (VALUE*)(args);
166
196
  rb_ary_push(*p_ret_array, rb_str_new_cstr(key.c_str()));
197
+ return GMatx::t_continue;
167
198
  }
168
199
 
169
200
  static VALUE t_ids(VALUE self)
@@ -207,6 +238,21 @@ static VALUE t_size(VALUE self)
207
238
  return INT2NUM(pMatx->size());
208
239
  }
209
240
 
241
+ static VALUE t_first(VALUE self)
242
+ {
243
+ class GMatx* pMatx = NULL;
244
+ Data_Get_Struct(self, class GMatx, pMatx);
245
+
246
+ std::string id;
247
+ t_key_value_hash row_hash = pMatx->first(id);
248
+ if (id.empty())
249
+ return Qnil;
250
+ VALUE ret_array = rb_ary_new();
251
+ rb_ary_push(ret_array, rb_str_new_cstr(id.c_str()));
252
+ rb_ary_push(ret_array, MatxHashUtil::key_value_hash_to_ruby_hash(row_hash));
253
+
254
+ return ret_array;
255
+ }
210
256
 
211
257
  VALUE cSMatrix;
212
258
 
@@ -220,7 +266,9 @@ extern "C" void Init_s_matrix()
220
266
  rb_define_method(cSMatrix, "to_s", (VALUE(*)(ANYARGS))t_to_s, 0);
221
267
  rb_define_method(cSMatrix, "add_row", (VALUE(*)(ANYARGS))t_add_row, 2);
222
268
  rb_define_method(cSMatrix, "get_row", (VALUE(*)(ANYARGS))t_get_row, 1);
269
+ rb_define_method(cSMatrix, "find", (VALUE(*)(ANYARGS))t_find, 1);
223
270
  rb_define_method(cSMatrix, "each", (VALUE(*)(ANYARGS))t_each, 0);
271
+ rb_define_method(cSMatrix, "first", (VALUE(*)(ANYARGS))t_first, 0);
224
272
  rb_define_method(cSMatrix, "all", (VALUE(*)(ANYARGS))t_all, 0);
225
273
  rb_define_method(cSMatrix, "ids", (VALUE(*)(ANYARGS))t_ids, 0);
226
274
  rb_define_method(cSMatrix, "keys", (VALUE(*)(ANYARGS))t_keys, 0);
@@ -1,5 +1,5 @@
1
1
  class SMatrix
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
4
4
 
5
5
  require "s_matrix/s_matrix"
data/spec/smatrix_spec.rb CHANGED
@@ -102,16 +102,19 @@ describe SMatrix do
102
102
  expect(a.all).to eq({})
103
103
  expect(a.ids).to eq([])
104
104
  expect(a.keys).to eq([])
105
+ expect(a.first).to eq(nil)
105
106
 
106
107
  a.add_row('2', {a: 2})
107
108
  expect(a.all).to eq({'2' => {'a' => '2'}})
108
109
  expect(a.ids).to eq(['2'])
109
110
  expect(a.keys).to eq(['a'])
111
+ expect(a.first).to eq(['2', {'a' => '2'}])
110
112
 
111
113
  a.add_row('2', {b: 3})
112
114
  expect(a.all).to eq({'2' => {'a' => nil, 'b' => '3'}})
113
115
  expect(a.ids).to eq(['2'])
114
116
  expect(a.keys).to eq(['a', 'b'])
117
+ expect(a.first).to eq(['2', {'a' => nil, 'b' => '3'}])
115
118
 
116
119
  a.add_row('3', {b: 3})
117
120
  expect(a.all).to eq({
@@ -120,6 +123,29 @@ describe SMatrix do
120
123
  })
121
124
  expect(a.ids).to eq(['2', '3'])
122
125
  expect(a.keys).to eq(['a', 'b'])
126
+ expect(a.first == ['2', {'a' => nil, 'b' => '3'}] || a.first == ['3', {'b' => '3'}]).to eq(true)
127
+ end
128
+ end
129
+
130
+ describe 'find' do
131
+ it '' do
132
+ a = SMatrix.new
133
+ expect( a.find({a: '2'}) ).to eq nil
134
+
135
+ a.add_row('223', {a: 2})
136
+ expect( a.find({a: '2'}) ).to eq ['223', {'a' => '2'}]
137
+
138
+ a.add_row('224', {a: 3})
139
+ expect( a.find({a: '2'}) ).to eq ['223', {'a' => '2'}]
140
+ expect( a.find({a: '3'}) ).to eq ['224', {'a' => '3'}]
141
+ expect( a.find({a: '3', b: nil}) ).to eq ['224', {'a' => '3'}]
142
+
143
+ a.add_row('225', {a: 2, b: 3})
144
+ expect( a.find({a: '2'})[0] == '223' || a.find({a: '2'})[0] == '224' ).to eq true
145
+ expect( a.find({b: '3'}) ).to eq ['225', {'a' => '2', 'b' => '3'}]
146
+ expect( a.find({a: '2', b: '3'}) ).to eq ['225', {'a' => '2', 'b' => '3'}]
147
+ expect( a.find({a: '2', b: '1'}) ).to eq nil
148
+ expect( a.find({a: nil, b: '3'}) ).to eq nil
123
149
  end
124
150
  end
125
151
 
data/todolist.txt CHANGED
@@ -1,16 +1,15 @@
1
1
  todolist:
2
2
 
3
3
  1. function with first priority:
4
- -done all
5
- -return {'23423' => {'name' => 'haha', 'hp' => '23425'}, '234232' => {} }
6
- -done ids
7
- -return ['233423', '234134']
8
- keys
9
- -return ['name', 'hp']
10
- first
4
+ -done all -return {'23423' => {'name' => 'haha', 'hp' => '23425'}, '234232' => {} }
5
+ -done ids -return ['233423', '234134']
6
+ -done keys -return ['name', 'hp']
7
+ -done first -return: ['23423', {'name' => 'haha', 'hp' => '23425'}]
8
+
11
9
  empty?
12
10
  include? {|k, v| k == '2323232'}
13
- find_by name: 'haha', hp: '2342'
11
+ -done find name: 'haha', hp: '2342' -return ['234232', {'name' => 'haha', 'hp' => '23425'}]
12
+ find_all name: 'haha', hp: '2342' -return [['234232', {'name' => 'haha', 'hp' => '23425'}], [], ...]
14
13
  select {|k, v| k == '2232'}
15
14
  merge
16
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s_matrix
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - zhangyuan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-19 00:00:00.000000000 Z
11
+ date: 2014-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -102,6 +102,8 @@ files:
102
102
  - ext/s_matrix/gmatx.h
103
103
  - ext/s_matrix/matx_content.cpp
104
104
  - ext/s_matrix/matx_content.h
105
+ - ext/s_matrix/matx_hash_util.cpp
106
+ - ext/s_matrix/matx_hash_util.h
105
107
  - ext/s_matrix/matx_row.cpp
106
108
  - ext/s_matrix/matx_row.h
107
109
  - ext/s_matrix/matx_string.h