PageRenderTime 11ms CodeModel.GetById 1ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/src/lib/numeric/natural_general.e

http://github.com/tybor/Liberty
Specman e | 383 lines | 232 code | 45 blank | 106 comment | 0 complexity | 995b20cecb0a9dab6358a85f5c905786 MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4deferred class NATURAL_GENERAL
  5   --
  6   -- General natural number abstraction to share common code for NATURAL_8, NATURAL_16, NATURAL_32 and
  7   -- NATURAL_64.
  8   --
  9   -- All implementations have a limited size (8, 16, 32 or 64 bits).
 10   -- As NATURAL_8, NATURAL_16, NATURAL_32 and NATURAL_64 are expanded classes, it is not possible to
 11   -- expect any form of polymorphism (but you are sure to get the very best execution speed).
 12   --
 13   -- See also INTEGER_8, INTEGER_16, INTEGER_32, INTEGER_64, NUMBER or MUTABLE_BIG_INTEGER.
 14   --
 15
 16inherit
 17   COMPARABLE
 18      redefine
 19         is_equal, fill_tagged_out_memory, out_in_tagged_out_memory, infix ">",
 20         infix "<=", infix ">="
 21      end
 22   HASHABLE --| **** TODO change to NUMERIC when NATURAL integration is complete
 23      redefine
 24         fill_tagged_out_memory, out_in_tagged_out_memory
 25      end
 26
 27insert
 28   PLATFORM
 29      redefine
 30         is_equal, fill_tagged_out_memory, out_in_tagged_out_memory
 31      end
 32
 33feature {ANY}
 34   infix "+" (other: like Current): like Current
 35         -- Sum with `other' (commutative).
 36      external "built_in"
 37      end
 38
 39   infix "-" (other: like Current): like Current
 40         -- Result of subtracting `other'.
 41      external "built_in"
 42      end
 43
 44   infix "*" (other: like Current): like Current
 45         -- Product by `other'.
 46      external "built_in"
 47      end
 48
 49   infix "/" (other: like Current): REAL
 50         -- Division by `other'.
 51      external "built_in"
 52      end
 53
 54   infix "//" (other: like Current): like Current
 55         -- Quotient of the Euclidian division of `Current' by `other'.
 56         -- The corresponding remainder is given by infix "\\".
 57         --
 58         -- See also infix "#//".
 59      external "built_in"
 60      end
 61
 62   infix "\\" (other: like Current): like Current
 63         -- Remainder of the Euclidian division of `Current' by `other'.
 64         -- By definition, `0 <= Result < other.abs'.
 65         --
 66         -- See also infix "#\\", infix "//".
 67      external "built_in"
 68      end
 69
 70   infix "<" (other: like Current): BOOLEAN
 71      external "built_in"
 72      end
 73
 74   infix "<=" (other: like Current): BOOLEAN
 75      external "built_in"
 76      end
 77
 78   infix ">" (other: like Current): BOOLEAN
 79      external "built_in"
 80      end
 81
 82   infix ">=" (other: like Current): BOOLEAN
 83      external "built_in"
 84      end
 85
 86   is_odd: BOOLEAN
 87         -- Is odd?
 88      deferred
 89      end
 90
 91   is_even: BOOLEAN
 92         -- Is even?
 93      deferred
 94      end
 95
 96   is_equal (other: like Current): BOOLEAN
 97      do
 98         Result := Current = other
 99      end
100
101feature {ANY} -- Conversions:
102   to_string: STRING
103         -- The decimal view of `Current' into a new allocated STRING.
104         -- For example, if `Current' is 3 the `Result' is "3".
105         --
106         -- See also `append_in', `to_string_format', `to_unicode_string'.
107      do
108         string_buffer.clear_count
109         append_in(string_buffer)
110         Result := string_buffer.twin
111      end
112
113   to_unicode_string: UNICODE_STRING
114         -- The decimal view of `Current' into a new allocated UNICODE_STRING.
115         -- For example, if `Current' is -1 the `Result' is U"-1".
116         --
117         -- See also `append_in_unicode', `to_unicode_string_format', `to_string'.
118      do
119         unicode_string_buffer.clear_count
120         append_in_unicode(unicode_string_buffer)
121         Result := unicode_string_buffer.twin
122      end
123
124   append_in_format (buffer: STRING; s: INTEGER)
125         -- Append in the `buffer' the equivalent of `to_string_format'.
126         -- If you look for performances, you should always prefer `append_in_format' which allow you
127         -- to recycle a unique common `buffer' (each call of `to_string_format' allocate a new object!).
128         --
129         -- See also `append_in', `append_in_unicode', `append_in_unicode_format'.
130      require
131         to_string.count <= s
132      local
133         i: INTEGER
134      do
135         string_buffer.clear_count
136         append_in(string_buffer)
137         from
138            i := s - string_buffer.count
139         until
140            i <= 0
141         loop
142            buffer.extend(' ')
143            i := i - 1
144         end
145         buffer.append(string_buffer)
146      ensure
147         buffer.count >= old buffer.count + s
148      end
149
150   append_in_unicode_format (buffer: UNICODE_STRING; s: INTEGER)
151         -- Append in the `buffer' the equivalent of `to_unicode_string_format'.
152         -- If you look for performances, you should always prefer `append_in_unicode_format' which allow
153         -- you to recycle a unique common `buffer' (each call of `to_unicode_string_format' allocate a
154         -- new object!).
155         --
156         -- See also `append_in_format', `append_in', `append_in_format'.
157      require
158         to_string.count <= s
159      local
160         i: INTEGER
161      do
162         unicode_string_buffer.clear_count
163         append_in_unicode(unicode_string_buffer)
164         from
165            i := s - unicode_string_buffer.count
166         until
167            i <= 0
168         loop
169            buffer.extend(' '.code)
170            i := i - 1
171         end
172         buffer.append(unicode_string_buffer)
173      ensure
174         buffer.count >= old buffer.count + s
175      end
176
177   decimal_digit: CHARACTER
178         -- Gives the corresponding CHARACTER for range 0..9.
179         --
180         -- See also `hexadecimal_digit'.
181      deferred
182      ensure
183         (once "0123456789").has(Result)
184      end
185
186   hexadecimal_digit: CHARACTER
187         -- Gives the corresponding CHARACTER for range 0..15.
188         --
189         -- See also `decimal_digit'.
190      deferred
191      ensure
192         (once "0123456789ABCDEF").has(Result)
193      end
194
195   to_character: CHARACTER
196         -- Return the corresponding ASCII character.
197         --
198         -- See also `to_boolean', `to_number', `to_string'.
199      deferred
200      end
201
202   to_number: NUMBER
203         -- Convert `Current' into a new allocated NUMBER.
204         --
205         -- See also `to_boolean', `to_string', `to_character', `to_hexadecimal'.
206      deferred
207      ensure
208         Result.to_string.is_equal(to_string)
209      end
210
211feature {ANY} -- Modular arithmetic (these wrap around on overflow)
212   infix "#+" (other: like Current): like Current
213      external "built_in"
214      end
215
216   infix "#-" (other: like Current): like Current
217      external "built_in"
218      end
219
220   infix "#\\" (other: like Current): like Current
221      external "built_in"
222      end
223
224   infix "#//" (other: like Current): like Current
225      external "built_in"
226      end
227
228feature {ANY} -- Object printing
229   out_in_tagged_out_memory, fill_tagged_out_memory
230      do
231         Current.append_in(tagged_out_memory)
232      end
233
234   to_hexadecimal: STRING
235      do
236         string_buffer.clear_count
237         to_hexadecimal_in(string_buffer)
238         Result := string_buffer.twin
239      end
240
241   to_hexadecimal_in (buffer: STRING)
242      local
243         index, timez: INTEGER;
244         value, val_mask: like Current
245      do
246         from
247            value := Current
248            timez := object_size * 2
249            index := buffer.count + timez
250            buffer.extend_multiple(' ', timez)
251         until
252            timez = 0
253         loop
254            val_mask := (value |>> 4) |<< 4
255            buffer.put((value - val_mask).hexadecimal_digit, index)
256            index := index - 1
257            value := value |>> 4
258            timez := timez - 1
259         end
260      end
261
262   append_in (buffer: STRING)
263         -- Append in the `buffer' the equivalent of `to_string'.
264         -- If you look for performances, you should always prefer `append_in' which allow you to recycle
265         -- a unique common `buffer' (each call of `to_string' allocate a new object!).
266         --
267         -- See also `append_in_format', `append_in_unicode', `append_in_unicode_format', `to_hexadecimal_in'.
268      require
269         buffer /= Void
270      deferred
271      end
272
273   append_in_unicode (buffer: UNICODE_STRING)
274         -- Append in the `buffer' the equivalent of `to_unicode_string'.
275         -- If you look for performances, you should always prefer `append_in_unicode' which allow you to recycle
276         -- a unique common `buffer' (each call of `to_unicode_string' allocate a new object!).
277         --
278         -- See also `append_in_unicode_format', `append_in', `append_in_format', `to_hexadecimal_in'.
279      require
280         buffer /= Void
281      deferred
282      end
283
284feature {ANY} -- Bitwise Logical Operators:
285   infix "#>>", bit_rotate_right (s: INTEGER_8): like Current
286         -- Rotate by `s' positions right.
287         --
288         -- See also `bit_rotate_left' and `bit_rotate'.
289      require
290         s.in_range(1, bit_count - 1)
291      external "built_in"
292      end
293
294   infix "#<<", bit_rotate_left (s: INTEGER_8): like Current
295         -- Rotate by `s' positions left.
296         --
297         -- See also `bit_rotate_right' and `bit_rotate'.
298      require
299         s.in_range(1, bit_count - 1)
300      external "built_in"
301      end
302
303   bit_rotate (s: INTEGER_8): like Current
304         -- Rotate by `s' positions (positive `s' shifts right, negative left
305         --
306         -- See also `bit_rotate_right' and `bit_rotate_left'.
307      require
308         s.in_range(- (bit_count - 1), bit_count - 1)
309      external "built_in"
310      end
311
312   prefix "~", bit_not: like Current
313         -- One's complement of `Current'.
314      external "built_in"
315      end
316
317   infix "&", bit_and (other: like Current): like Current
318         -- Bitwise logical and of `Current' with `other'.
319      external "built_in"
320      end
321
322   infix "|", bit_or (other: like Current): like Current
323         -- Bitwise logical inclusive or of `Current' with `other'.
324      external "built_in"
325      end
326
327   bit_xor (other: like Current): like Current
328         -- Bitwise logical exclusive or of `Current' with `other'.
329      external "built_in"
330      end
331
332   infix "|>>", bit_shift_right (s: INTEGER_8): like Current
333         -- Shift by `s' positions right (sign bit copied) bits falling off the end are lost.
334      external "built_in"
335      end
336
337   infix "|<<", bit_shift_left (s: INTEGER_8): like Current
338         -- Shift by `s' positions left bits falling off the end are lost.
339      external "built_in"
340      end
341
342feature {ANY} -- Size query
343   bit_count: INTEGER_8
344         -- The number of bits used to store the value of Current
345                 -- (it is 8 for NATURAL_8, 16 for NATURAL_16 and so on)
346         -- This is actually used only for assertion here, in NATURAL_GENERAL.
347      deferred
348      ensure
349         Result = (object_size * 8)
350      end
351
352feature {}
353   string_buffer: STRING
354      once
355         create Result.make(128)
356      end
357
358   unicode_string_buffer: UNICODE_STRING
359      once
360         create Result.make(128)
361      end
362
363end -- class NATURAL_GENERAL
364--
365-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
366--
367-- Permission is hereby granted, free of charge, to any person obtaining a copy
368-- of this software and associated documentation files (the "Software"), to deal
369-- in the Software without restriction, including without limitation the rights
370-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
371-- copies of the Software, and to permit persons to whom the Software is
372-- furnished to do so, subject to the following conditions:
373--
374-- The above copyright notice and this permission notice shall be included in
375-- all copies or substantial portions of the Software.
376--
377-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
378-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
379-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
380-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
381-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
382-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
383-- THE SOFTWARE.