multiarray 0.2.4 → 0.4.0

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.
@@ -7,198 +7,170 @@ module Hornetseye
7
7
 
8
8
  class << self
9
9
 
10
- # Allocate +Storage+ object for storing a value
10
+ # Returns the dereferenced type for pointers
11
11
  #
12
- # @return [Storage] Object for storing a value of this type.
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 typecode
16
+ def dereference
32
17
  self
33
18
  end
34
19
 
35
- # Returns the element type for arrays and composite numbers
20
+ # Returns the element type for arrays
36
21
  #
37
- # Otherwise it returns +self+.
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
- # Check whether an array is empty or not
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<Integer>] Returns +[]+.
33
+ # @return [Array] Returns +[]+.
60
34
  def shape
61
35
  []
62
36
  end
63
37
 
64
- # Get number of elements of multi-dimensional array
38
+ # Number of elements
65
39
  #
66
- # Returns +1+ if this is not an array.
40
+ # @return [Integer] Number of elements
67
41
  #
68
- # @return [Integer] Number of elements of array. +1+ if this is not an
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
- end
47
+ def ===( other )
48
+ ( other == self ) or ( other.is_a? self ) or ( other.class == self )
49
+ end
75
50
 
76
- # Get +Storage+ object used to store the data of this instance
77
- #
78
- # @return [Storage]
79
- #
80
- # @private
81
- attr_accessor :storage
51
+ end
82
52
 
83
- # Get number of bytes memory required to store the data of an instance
84
- #
85
- # @return [Integer] Number of bytes.
53
+ # Create new instance of this type
86
54
  #
87
- # @private
88
- def bytesize
89
- self.class.bytesize
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
- # Returns the element type for arrays
93
- #
94
- # Otherwise it returns +self.class+.
60
+ # Display type and value of this instance
95
61
  #
96
- # @return [Class] Element type for arrays. Returns +self.class+ if this is
97
- # not an array.
98
- def typecode
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
- # Returns the element type for arrays and composite numbers
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
- # @private
110
- def basetype
111
- self.class.basetype
69
+ # @return [String] Returns string with the value of this instance.
70
+ def to_s
71
+ get.to_s
112
72
  end
113
-
114
- # Check whether an array is empty or not
115
- #
116
- # Returns +false+ if this is not an array.
73
+
74
+ # Retrieve Ruby value of object
117
75
  #
118
- # @return [FalseClass,TrueClass] Returns boolean indicating whether the
119
- # array is empty or not. Returns +false+ if this is not an array.
120
- def empty?
121
- self.class.empty?
76
+ # @return [Object] Ruby value of native data type.
77
+ def []
78
+ get
122
79
  end
123
80
 
124
- # Get shape of multi-dimensional array
81
+ # Set Ruby value of object
125
82
  #
126
- # Returns +[]+ if this is not an array.
83
+ # @param [Object] value New Ruby value for native data type.
127
84
  #
128
- # @return [Array<Integer>] Returns shape of array or +[]+ if this is not
129
- # an array.
130
- def shape
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
- # Get number of elements of multi-dimensional array
90
+ # Retrieve Ruby value of object
135
91
  #
136
- # Returns +1+ if this is not an array.
92
+ # @return [Object] Ruby value of native data type.
137
93
  #
138
- # @return [Integer] Number of elements of array. +1+ if this is not an
139
- # array.
140
- def size
141
- self.class.size
94
+ # @private
95
+ def get
96
+ delay.instance_exec { @value }
142
97
  end
143
98
 
144
- # Create new instance of this type
99
+ # Set Ruby value of object
100
+ #
101
+ # Set to specified value.
145
102
  #
146
- # @param value [Object] Optional initial value for this instance.
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
- # @see alloc
105
+ # @return [Object] The parameter +value+ or the default value.
151
106
  #
152
107
  # @private
153
- def initialize( value = nil, options = {} )
154
- @storage = options[ :storage ] ? options[ :storage ] : self.class.alloc
155
- set value unless value.nil?
108
+ def set( value )
109
+ @value = value
156
110
  end
157
111
 
158
- # Display type and value of this instance
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
- # Display value of this instance
166
- #
167
- # @return [String] Returns string with the value of this instance.
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
- # Convert value of this instance to array
173
- #
174
- # @return [Array] Result of calling +to_a+ on value of this instance.
175
- def to_a
176
- get.to_a
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
- # Retrieve element of array
180
- #
181
- # @param *indices [Array<Integer>] Index/indices to access element.
182
- # @return [Object,Type] Ruby object with value of element.
183
- #
184
- # @see #[]
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
- alias_method :[], :at
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
- # Assign value to element of array
192
- #
193
- # @param *args [Array<Integer,Object>] Index/indices to access element.
194
- # The last element of +args+ is the new value to store in the array.
195
- #
196
- # @return [Object] Returns +args.last+.
197
- def assign( *args )
198
- sel( *args[ 0 ... -1 ] ).set args.last
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
- alias_method :[]=, :assign
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
- for t in @@types
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
- for t in @@types
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 test_typecode
52
- for t in @@types
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 test_shape
58
- for t in @@types
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 test_size
64
- for t in @@types
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 test_to_s
70
- for t in @@types
71
- assert_equal '42', t.new( 42 ).to_s
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 test_inspect
76
- for t in @@types
77
- assert_equal "#{t.inspect}(42)", t.new( 42 ).inspect
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 test_get_set
82
- for t in @@types
83
- i = t.new 0
84
- assert_equal 0, i.get
85
- assert_equal 42, i.set( 42 )
86
- assert_equal 42, i.get
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 test_at_assign
93
- for t in @@types
94
- i = t.new 0
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 test_op
110
- for t in @@types
111
- i = t.new 1
112
- assert_equal 3, i.op( 2 ) { |x| set get + x }.get
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