multiarray 0.2.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -2
- data/lib/multiarray.rb +45 -20
- data/lib/multiarray/int.rb +1 -1
- data/lib/multiarray/int_.rb +87 -60
- data/lib/multiarray/lazy.rb +76 -0
- data/lib/multiarray/list.rb +33 -74
- data/lib/multiarray/malloc.rb +11 -0
- data/lib/multiarray/multiarray.rb +19 -1
- data/lib/multiarray/object.rb +36 -19
- data/lib/multiarray/pointer.rb +11 -0
- data/lib/multiarray/pointer_.rb +223 -0
- data/lib/multiarray/sequence.rb +14 -10
- data/lib/multiarray/sequence_.rb +40 -106
- data/lib/multiarray/type.rb +101 -129
- data/test/tc_int.rb +78 -76
- data/test/tc_multiarray.rb +97 -15
- data/test/tc_object.rb +52 -45
- data/test/tc_sequence.rb +89 -106
- data/test/ts_multiarray.rb +0 -1
- metadata +6 -8
- data/lib/multiarray/composite_type.rb +0 -67
- data/lib/multiarray/descriptortype.rb +0 -43
- data/lib/multiarray/memory.rb +0 -112
- data/lib/multiarray/sequence_operation.rb +0 -52
- data/lib/multiarray/storage.rb +0 -23
- data/lib/multiarray/type_operation.rb +0 -32
data/lib/multiarray/type.rb
CHANGED
@@ -7,198 +7,170 @@ module Hornetseye
|
|
7
7
|
|
8
8
|
class << self
|
9
9
|
|
10
|
-
#
|
10
|
+
# Returns the dereferenced type for pointers
|
11
11
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# @private
|
15
|
-
def alloc
|
16
|
-
storage.alloc bytesize
|
17
|
-
end
|
18
|
-
|
19
|
-
# Create new instance viewing the data of the indicated +Storage+ object
|
20
|
-
#
|
21
|
-
# @return [Type] Object of this class.
|
22
|
-
#
|
23
|
-
# @private
|
24
|
-
def wrap( storage )
|
25
|
-
new nil, :storage => storage
|
26
|
-
end
|
27
|
-
|
28
|
-
# Returns the element type for arrays. Otherwise it returns +self+
|
12
|
+
# Returns the dereferenced type for pointers.
|
13
|
+
# Otherwise it returns +self+.
|
29
14
|
#
|
30
15
|
# @return [Class] Returns +self+.
|
31
|
-
def
|
16
|
+
def dereference
|
32
17
|
self
|
33
18
|
end
|
34
19
|
|
35
|
-
# Returns the element type for arrays
|
20
|
+
# Returns the element type for arrays
|
36
21
|
#
|
37
|
-
#
|
22
|
+
# Returns +self+ if this is not an array.
|
38
23
|
#
|
39
24
|
# @return [Class] Returns +self+.
|
40
|
-
|
41
|
-
# @private
|
42
|
-
def basetype
|
25
|
+
def typecode
|
43
26
|
self
|
44
27
|
end
|
45
28
|
|
46
|
-
#
|
47
|
-
#
|
48
|
-
# Returns +false+ if this is not an array.
|
49
|
-
#
|
50
|
-
# @return [FalseClass,TrueClass] Returns +false+.
|
51
|
-
def empty?
|
52
|
-
size == 0
|
53
|
-
end
|
54
|
-
|
55
|
-
# Get shape of multi-dimensional array
|
29
|
+
# Dimensions of arrays
|
56
30
|
#
|
57
31
|
# Returns +[]+ if this is not an array.
|
58
32
|
#
|
59
|
-
# @return [Array
|
33
|
+
# @return [Array] Returns +[]+.
|
60
34
|
def shape
|
61
35
|
[]
|
62
36
|
end
|
63
37
|
|
64
|
-
#
|
38
|
+
# Number of elements
|
65
39
|
#
|
66
|
-
#
|
40
|
+
# @return [Integer] Number of elements
|
67
41
|
#
|
68
|
-
# @return [Integer]
|
69
|
-
# array.
|
42
|
+
# @return [Integer] Returns +1+.
|
70
43
|
def size
|
71
44
|
shape.inject( 1 ) { |a,b| a * b }
|
72
45
|
end
|
73
46
|
|
74
|
-
|
47
|
+
def ===( other )
|
48
|
+
( other == self ) or ( other.is_a? self ) or ( other.class == self )
|
49
|
+
end
|
75
50
|
|
76
|
-
|
77
|
-
#
|
78
|
-
# @return [Storage]
|
79
|
-
#
|
80
|
-
# @private
|
81
|
-
attr_accessor :storage
|
51
|
+
end
|
82
52
|
|
83
|
-
#
|
84
|
-
#
|
85
|
-
# @return [Integer] Number of bytes.
|
53
|
+
# Create new instance of this type
|
86
54
|
#
|
87
|
-
# @
|
88
|
-
def
|
89
|
-
|
55
|
+
# @param [Object] value Optional initial value for this instance.
|
56
|
+
def initialize( value = self.class.default )
|
57
|
+
set value
|
90
58
|
end
|
91
59
|
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# Otherwise it returns +self.class+.
|
60
|
+
# Display type and value of this instance
|
95
61
|
#
|
96
|
-
# @return [
|
97
|
-
|
98
|
-
|
99
|
-
self.class.typecode
|
62
|
+
# @return [String] Returns string with information about type and value.
|
63
|
+
def inspect
|
64
|
+
"#{self.class.inspect}(#{@value.inspect})"
|
100
65
|
end
|
101
66
|
|
102
|
-
#
|
103
|
-
#
|
104
|
-
# Otherwise it returns +self.class+.
|
105
|
-
#
|
106
|
-
# @return [Class] Element type for arrays and composite numbers. Returns
|
107
|
-
# +self.class+ if this is not an array.
|
67
|
+
# Display value of this instance
|
108
68
|
#
|
109
|
-
# @
|
110
|
-
def
|
111
|
-
|
69
|
+
# @return [String] Returns string with the value of this instance.
|
70
|
+
def to_s
|
71
|
+
get.to_s
|
112
72
|
end
|
113
|
-
|
114
|
-
#
|
115
|
-
#
|
116
|
-
# Returns +false+ if this is not an array.
|
73
|
+
|
74
|
+
# Retrieve Ruby value of object
|
117
75
|
#
|
118
|
-
# @return [
|
119
|
-
|
120
|
-
|
121
|
-
self.class.empty?
|
76
|
+
# @return [Object] Ruby value of native data type.
|
77
|
+
def []
|
78
|
+
get
|
122
79
|
end
|
123
80
|
|
124
|
-
#
|
81
|
+
# Set Ruby value of object
|
125
82
|
#
|
126
|
-
#
|
83
|
+
# @param [Object] value New Ruby value for native data type.
|
127
84
|
#
|
128
|
-
# @return [
|
129
|
-
|
130
|
-
|
131
|
-
self.class.shape
|
85
|
+
# @return [Object] The parameter +value+ or the default value.
|
86
|
+
def []=( value )
|
87
|
+
set value
|
132
88
|
end
|
133
89
|
|
134
|
-
#
|
90
|
+
# Retrieve Ruby value of object
|
135
91
|
#
|
136
|
-
#
|
92
|
+
# @return [Object] Ruby value of native data type.
|
137
93
|
#
|
138
|
-
# @
|
139
|
-
|
140
|
-
|
141
|
-
self.class.size
|
94
|
+
# @private
|
95
|
+
def get
|
96
|
+
delay.instance_exec { @value }
|
142
97
|
end
|
143
98
|
|
144
|
-
#
|
99
|
+
# Set Ruby value of object
|
100
|
+
#
|
101
|
+
# Set to specified value.
|
145
102
|
#
|
146
|
-
# @param
|
147
|
-
# @option options [Storage] :storage (self.class.alloc) Use specified
|
148
|
-
# +Storage+ object instead of creating a new one.
|
103
|
+
# @param [Object] value New Ruby value for native data type.
|
149
104
|
#
|
150
|
-
# @
|
105
|
+
# @return [Object] The parameter +value+ or the default value.
|
151
106
|
#
|
152
107
|
# @private
|
153
|
-
def
|
154
|
-
@
|
155
|
-
set value unless value.nil?
|
108
|
+
def set( value )
|
109
|
+
@value = value
|
156
110
|
end
|
157
111
|
|
158
|
-
|
159
|
-
|
160
|
-
# @return [String] Returns string with information about type and value.
|
161
|
-
def inspect
|
162
|
-
"#{self.class.inspect}(#{to_s})"
|
112
|
+
def fetch
|
113
|
+
self
|
163
114
|
end
|
164
115
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
def to_s
|
169
|
-
get.to_s
|
116
|
+
def operation( *args, &action )
|
117
|
+
instance_exec *args.collect { |arg| arg.force.fetch.get }, &action
|
118
|
+
self
|
170
119
|
end
|
171
120
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
121
|
+
def delay
|
122
|
+
if not Thread.current[ :lazy ] or @value.is_a? Lazy
|
123
|
+
self
|
124
|
+
else
|
125
|
+
self.class.new Lazy.new( self )
|
126
|
+
end
|
177
127
|
end
|
178
128
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
def at( *indices )
|
186
|
-
sel( *indices ).get
|
129
|
+
def force
|
130
|
+
if Thread.current[ :lazy ] or not @value.is_a? Lazy
|
131
|
+
self
|
132
|
+
else
|
133
|
+
@value.force
|
134
|
+
end
|
187
135
|
end
|
188
136
|
|
189
|
-
|
137
|
+
def -@
|
138
|
+
if is_a?( Pointer_ ) and self.class.primitive < Sequence_
|
139
|
+
retval = self.class.new
|
140
|
+
else
|
141
|
+
retval = self.class.dereference.new
|
142
|
+
end
|
143
|
+
retval.operation( self ) { |x| set -x }
|
144
|
+
retval
|
145
|
+
end
|
190
146
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
147
|
+
def +@
|
148
|
+
self
|
149
|
+
end
|
150
|
+
|
151
|
+
def +( other )
|
152
|
+
if is_a?( Pointer_ ) and self.class.primitive < Sequence_
|
153
|
+
retval = self.class.new
|
154
|
+
else
|
155
|
+
retval = self.class.dereference.new
|
156
|
+
end
|
157
|
+
retval.operation( self, other ) { |x,y| set x + y }
|
158
|
+
retval
|
199
159
|
end
|
200
160
|
|
201
|
-
|
161
|
+
def match( value, context = nil )
|
162
|
+
retval = fit value
|
163
|
+
retval = retval.align context if context
|
164
|
+
retval
|
165
|
+
end
|
166
|
+
|
167
|
+
def ==( other )
|
168
|
+
if other.class == self.class
|
169
|
+
other.get == get
|
170
|
+
else
|
171
|
+
false
|
172
|
+
end
|
173
|
+
end
|
202
174
|
|
203
175
|
end
|
204
176
|
|
data/test/tc_int.rb
CHANGED
@@ -1,115 +1,117 @@
|
|
1
1
|
require 'test/unit'
|
2
|
+
begin
|
3
|
+
require 'rubygems'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
2
6
|
Kernel::require 'multiarray'
|
3
7
|
|
4
8
|
class TC_Int < Test::Unit::TestCase
|
5
9
|
|
10
|
+
U8 = Hornetseye::UBYTE
|
11
|
+
S8 = Hornetseye::BYTE
|
12
|
+
U16 = Hornetseye::USINT
|
13
|
+
S16 = Hornetseye::SINT
|
14
|
+
U32 = Hornetseye::UINT
|
15
|
+
S32 = Hornetseye::INT
|
16
|
+
U64 = Hornetseye::ULONG
|
17
|
+
S64 = Hornetseye::LONG
|
18
|
+
|
19
|
+
T = [ U8, S8, U16, S16, U32, S32 ]
|
20
|
+
INSPECT = {
|
21
|
+
U8 => 'UBYTE', S8 => 'BYTE',
|
22
|
+
U16 => 'USINT', S16 => 'SINT',
|
23
|
+
U32 => 'UINT', S32 => 'INT'
|
24
|
+
}
|
25
|
+
SIGNED = {
|
26
|
+
U8 => false, S8 => true,
|
27
|
+
U16 => false, S16 => true,
|
28
|
+
U32 => false, S32 => true
|
29
|
+
}
|
30
|
+
|
31
|
+
def lazy( &action )
|
32
|
+
Hornetseye::lazy &action
|
33
|
+
end
|
34
|
+
|
35
|
+
def eager( &action )
|
36
|
+
Hornetseye::eager &action
|
37
|
+
end
|
38
|
+
|
6
39
|
def setup
|
7
|
-
@@types = [ Hornetseye::UBYTE,
|
8
|
-
Hornetseye::BYTE,
|
9
|
-
Hornetseye::USINT,
|
10
|
-
Hornetseye::SINT,
|
11
|
-
Hornetseye::UINT,
|
12
|
-
Hornetseye::INT,
|
13
|
-
Hornetseye::ULONG,
|
14
|
-
Hornetseye::LONG ]
|
15
40
|
end
|
16
41
|
|
17
42
|
def teardown
|
18
|
-
@@types = nil
|
19
43
|
end
|
20
44
|
|
21
45
|
def test_int_default
|
22
|
-
|
23
|
-
assert_equal 0, t.default
|
24
|
-
end
|
46
|
+
T.each { |t| assert_equal 0, t.new[] }
|
25
47
|
end
|
26
48
|
|
27
|
-
def test_int_to_s
|
28
|
-
assert_equal 'UBYTE', Hornetseye::UBYTE.to_s
|
29
|
-
assert_equal 'BYTE' , Hornetseye::BYTE.to_s
|
30
|
-
assert_equal 'USINT', Hornetseye::USINT.to_s
|
31
|
-
assert_equal 'SINT' , Hornetseye::SINT.to_s
|
32
|
-
assert_equal 'UINT' , Hornetseye::UINT.to_s
|
33
|
-
assert_equal 'INT' , Hornetseye::INT.to_s
|
34
|
-
assert_equal 'ULONG', Hornetseye::ULONG.to_s
|
35
|
-
assert_equal 'LONG' , Hornetseye::LONG.to_s
|
36
|
-
end
|
37
49
|
|
38
50
|
def test_int_inspect
|
39
|
-
|
40
|
-
assert_equal t.to_s, t.inspect
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_bytesize
|
45
|
-
for i in [ 8, 16, 32, 64 ]
|
46
|
-
assert_equal i, 8 * Hornetseye::INT( i, Hornetseye::UNSIGNED ).bytesize
|
47
|
-
assert_equal i, 8 * Hornetseye::INT( i, Hornetseye::SIGNED ).bytesize
|
48
|
-
end
|
51
|
+
T.each { |t| assert_equal INSPECT[ t ], t.inspect }
|
49
52
|
end
|
50
53
|
|
51
|
-
def
|
52
|
-
|
53
|
-
assert_equal t, t.typecode
|
54
|
-
end
|
54
|
+
def test_int_to_s
|
55
|
+
T.each { |t| assert_equal INSPECT[ t ], t.to_s }
|
55
56
|
end
|
56
57
|
|
57
|
-
def
|
58
|
-
|
59
|
-
assert_equal [], t.shape
|
60
|
-
end
|
58
|
+
def test_inspect
|
59
|
+
T.each { |t| assert_equal "#{t}(42)", t.new( 42 ).inspect }
|
61
60
|
end
|
62
61
|
|
63
|
-
def
|
64
|
-
|
65
|
-
assert_equal 1, t.size
|
66
|
-
end
|
62
|
+
def test_to_s
|
63
|
+
T.each { |t| assert_equal '42', t.new( 42 ).to_s }
|
67
64
|
end
|
68
65
|
|
69
|
-
def
|
70
|
-
|
71
|
-
assert_equal
|
66
|
+
def test_marshal
|
67
|
+
T.each do |t|
|
68
|
+
assert_equal t.new( 42 ),
|
69
|
+
Marshal.load( Marshal.dump( t.new( 42 ) ) )
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
73
|
+
def test_at_assign
|
74
|
+
T.each do |t|
|
75
|
+
i = t.new 3
|
76
|
+
assert_equal 3, i[]
|
77
|
+
assert_equal 42, i[] = 42
|
78
|
+
assert_equal 42, i[]
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
assert_equal 0, i.set
|
88
|
-
assert_equal 0, i.get
|
82
|
+
def test_equal
|
83
|
+
T.each do |t1|
|
84
|
+
T.each do |t2|
|
85
|
+
assert_not_equal t1.new( 3 ), t2.new( 4 )
|
86
|
+
assert_equal t1 == t2, t1.new( 3 ) == t2.new( 3 )
|
87
|
+
end
|
89
88
|
end
|
90
89
|
end
|
91
90
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
assert_equal 0, i.at
|
96
|
-
assert_equal 42, i.assign( 42 )
|
97
|
-
assert_equal 42, i.at
|
98
|
-
assert_raise( ArgumentError ) { i.at 0 }
|
99
|
-
assert_raise( ArgumentError ) { i.assign 0, 0 }
|
100
|
-
i = t.new 0
|
101
|
-
assert_equal 0, i[]
|
102
|
-
assert_equal 42, i[] = 42
|
103
|
-
assert_equal 42, i[]
|
104
|
-
assert_raise( ArgumentError ) { i[ 0 ] }
|
105
|
-
assert_raise( ArgumentError ) { i[ 0 ] = 0 }
|
91
|
+
def test_negate
|
92
|
+
T.select { |t| SIGNED[ t ] }.each do |t|
|
93
|
+
assert_equal t.new( -5 ), -t.new( 5 )
|
106
94
|
end
|
107
95
|
end
|
108
96
|
|
109
|
-
def
|
110
|
-
|
111
|
-
i = t.new
|
112
|
-
|
97
|
+
def test_lazy
|
98
|
+
T.select { |t| SIGNED[ t ] }.each do |t|
|
99
|
+
i = lazy { -t.new( 3 ) }
|
100
|
+
assert_not_equal t.new( -3 ), i
|
101
|
+
assert_equal "#{t}(<delayed>)", i.inspect
|
102
|
+
assert_equal t.new( -3 ), i.force
|
103
|
+
i = lazy { --t.new( 3 ) }
|
104
|
+
assert_equal "#{t}(<delayed>)", i.inspect
|
105
|
+
assert_equal t.new( 3 ), i.force
|
106
|
+
i = -lazy { -t.new( 3 ) }
|
107
|
+
assert_equal t.new( 3 ), i
|
108
|
+
i = lazy { -lazy { -t.new( 3 ) } }
|
109
|
+
assert_equal "#{t}(<delayed>)", i.inspect
|
110
|
+
assert_equal t.new( 3 ), i.force
|
111
|
+
i = eager { lazy { -t.new( 3 ) } }
|
112
|
+
assert_equal "#{t}(<delayed>)", i.inspect
|
113
|
+
i = lazy { eager { -lazy { -t.new( 3 ) } } }
|
114
|
+
assert_equal t.new( 3 ), i
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|