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