/src/lib/storage/collection2.e

http://github.com/tybor/Liberty · Specman e · 433 lines · 317 code · 39 blank · 77 comment · 9 complexity · 54c16a7ce3a37b92092a7af1f60616a7 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 COLLECTION2[E_]
  5. --
  6. -- Abstract definition of a 2 dimensional collection of elements of type E_.
  7. --
  8. -- The Liberty Eiffel standard library provides two implementations of COLLECTION2: ARRAY2 and FIXED_ARRAY2.
  9. -- All implementations have exactly the same behavior. Switching from one implementation to
  10. -- another only change the memory used and the execution time.
  11. --
  12. insert
  13. SAFE_EQUAL[E_]
  14. undefine copy
  15. redefine fill_tagged_out_memory, is_equal
  16. end
  17. feature {ANY} -- Indexing:
  18. lower1, lower2: INTEGER
  19. -- Lower index bounds.
  20. deferred
  21. end
  22. frozen line_minimum: INTEGER
  23. -- Equivalent of `lower1'.
  24. do
  25. Result := lower1
  26. end
  27. frozen column_minimum: INTEGER
  28. -- Equivalent of `lower2'.
  29. do
  30. Result := lower2
  31. end
  32. upper1, upper2: INTEGER
  33. -- Upper index bounds.
  34. deferred
  35. end
  36. frozen line_maximum: INTEGER
  37. -- Equivalent of `upper1'.
  38. do
  39. Result := upper1
  40. end
  41. frozen column_maximum: INTEGER
  42. -- Equivalent of `upper2'.
  43. do
  44. Result := upper2
  45. end
  46. feature {ANY} -- Reading:
  47. item (line, column: INTEGER): E_
  48. require
  49. valid_index(line, column)
  50. deferred
  51. end
  52. feature {ANY} -- Writing:
  53. put (element: like item; line, column: INTEGER) assign item
  54. require
  55. valid_index(line, column)
  56. deferred
  57. ensure
  58. item(line, column) = element
  59. end
  60. force (element: like item; line, column: INTEGER)
  61. -- Put `element' at position (`line',`column'). Collection
  62. -- resized first when (`line',`column') is not inside current
  63. -- bounds. New bounds are initialized with default values.
  64. require
  65. line >= 0
  66. column >= 0
  67. deferred
  68. ensure
  69. item(line, column) = element
  70. count >= old count
  71. end
  72. feature {ANY} -- Index validity:
  73. frozen valid_line, valid_index1 (line: INTEGER): BOOLEAN
  74. do
  75. Result := lower1 <= line and then line <= upper1
  76. ensure
  77. Result = (lower1 <= line and line <= upper1)
  78. end
  79. frozen valid_column, valid_index2 (column: INTEGER): BOOLEAN
  80. do
  81. Result := lower2 <= column and then column <= upper2
  82. ensure
  83. Result = (lower2 <= column and column <= upper2)
  84. end
  85. frozen valid_index (line, column: INTEGER): BOOLEAN
  86. do
  87. Result := lower1 <= line and then line <= upper1 and then lower2 <= column and then column <= upper2
  88. ensure
  89. Result = (valid_line(line) and valid_column(column))
  90. end
  91. feature {ANY} -- Counting:
  92. count1: INTEGER
  93. -- Size of the first dimension.
  94. deferred
  95. ensure
  96. Result = upper1 - lower1 + 1
  97. end
  98. frozen line_count: INTEGER
  99. -- Equivalent of `count1'.
  100. do
  101. Result := count1
  102. end
  103. count2: INTEGER
  104. -- Size of the second dimension.
  105. deferred
  106. ensure
  107. Result = upper2 - lower2 + 1
  108. end
  109. frozen column_count: INTEGER
  110. do
  111. Result := count2
  112. end
  113. count: INTEGER
  114. -- Total number of elements.
  115. deferred
  116. ensure
  117. Result = line_count * column_count
  118. end
  119. feature {ANY}
  120. swap (line1, column1, line2, column2: INTEGER)
  121. -- Swap the element at index (`line1',`column1') with the
  122. -- the element at index (`line2',`column2').
  123. require
  124. valid_index(line1, column1)
  125. valid_index(line2, column2)
  126. deferred
  127. ensure
  128. item(line1, column1) = old item(line2, column2)
  129. item(line2, column2) = old item(line1, column1)
  130. count = old count
  131. end
  132. set_all_with (v: like item)
  133. -- Set all item with value `v'.
  134. deferred
  135. ensure
  136. count = old count
  137. end
  138. frozen clear_all
  139. -- Set all items to default values.
  140. local
  141. value: like item
  142. do
  143. set_all_with(value)
  144. ensure
  145. count = old count
  146. all_default
  147. end
  148. feature {ANY} -- Creating or initializing:
  149. from_collection2 (model: COLLECTION2[like item])
  150. -- Uses `model' to initialize Current.
  151. require
  152. model /= Void
  153. deferred
  154. ensure
  155. count1 = model.count1
  156. count2 = model.count2
  157. end
  158. from_model (model: COLLECTION[COLLECTION[E_]])
  159. -- The `model' is used to fill line by line Current.
  160. -- Assume all sub-collections of `model' have the same
  161. -- number of lines.
  162. require
  163. model.count >= 0
  164. model.count > 0 implies model.first.count >= 0
  165. deferred
  166. ensure
  167. count1 = model.count
  168. count1 > 0 implies count2 = model.first.count
  169. count1 = 0 implies count2 = 0
  170. end
  171. feature {ANY} -- Looking and comparison:
  172. all_default: BOOLEAN
  173. -- Do all items have their type's default value?
  174. deferred
  175. end
  176. fast_is_equal (other: like Current): BOOLEAN
  177. -- Do both collections have the same `lower1', `lower2', `upper1' and `upper2', and items?
  178. -- The basic `=' is used for comparison of items.
  179. -- See also `is_equal'.
  180. local
  181. line, column: INTEGER
  182. do
  183. if lower1 /= other.lower1 then
  184. elseif upper1 /= other.upper1 then
  185. elseif lower2 /= other.lower2 then
  186. elseif upper2 /= other.upper2 then
  187. else
  188. from
  189. Result := True
  190. line := upper1
  191. until
  192. not Result or else line < lower1
  193. loop
  194. from
  195. column := upper2
  196. until
  197. not Result or else column < lower2
  198. loop
  199. Result := item(line, column) = other.item(line, column)
  200. column := column - 1
  201. end
  202. line := line - 1
  203. end
  204. end
  205. end
  206. is_equal (other: like Current): BOOLEAN
  207. -- Do both collections have the same `lower1', `lower2', `upper1' and `upper2', and items?
  208. -- Feature `is_equal' is used for comparison of items.
  209. -- See also `fast_is_equal'.
  210. local
  211. line, column: INTEGER
  212. do
  213. if lower1 /= other.lower1 then
  214. elseif upper1 /= other.upper1 then
  215. elseif lower2 /= other.lower2 then
  216. elseif upper2 /= other.upper2 then
  217. else
  218. from
  219. Result := True
  220. line := upper1
  221. until
  222. not Result or else line < lower1
  223. loop
  224. from
  225. column := upper2
  226. until
  227. not Result or else column < lower2
  228. loop
  229. Result := safe_equal(item(line, column), other.item(line, column))
  230. column := column - 1
  231. end
  232. line := line - 1
  233. end
  234. end
  235. end
  236. is_equal_map (other: like Current): BOOLEAN
  237. -- Do both collections have the same `lower', `upper', and
  238. -- items?
  239. -- Feature `is_equal' is used for comparison of items.
  240. obsolete "Use `is_equal' instead."
  241. do
  242. Result := is_equal(other)
  243. end
  244. feature {ANY} -- Printing:
  245. frozen fill_tagged_out_memory
  246. local
  247. line, column: INTEGER; v: like item
  248. do
  249. tagged_out_memory.append(once "lower1: ")
  250. lower1.append_in(tagged_out_memory)
  251. tagged_out_memory.append(once " upper1: ")
  252. upper1.append_in(tagged_out_memory)
  253. tagged_out_memory.append(once " lower2: ")
  254. lower2.append_in(tagged_out_memory)
  255. tagged_out_memory.append(once " upper2: ")
  256. upper2.append_in(tagged_out_memory)
  257. tagged_out_memory.append(once " [%N")
  258. from
  259. line := lower1
  260. until
  261. line > upper1 or else tagged_out_memory.count > 4096
  262. loop
  263. tagged_out_memory.append(once "line ")
  264. line.append_in(tagged_out_memory)
  265. tagged_out_memory.append(once "%T: ")
  266. from
  267. column := lower2
  268. until
  269. column > upper2
  270. loop
  271. v := item(line, column)
  272. if v = Void then
  273. tagged_out_memory.append(once "Void")
  274. else
  275. v.out_in_tagged_out_memory
  276. end
  277. tagged_out_memory.extend(' ')
  278. column := column + 1
  279. end
  280. tagged_out_memory.extend('%N')
  281. line := line + 1
  282. end
  283. if valid_line(line) then
  284. tagged_out_memory.append(once "......%N")
  285. end
  286. end
  287. feature {ANY} -- Miscellaneous features:
  288. occurrences (elt: E_): INTEGER
  289. -- Number of occurrences using `is_equal'.
  290. -- See also `fast_occurrences' to choose the appropriate one.
  291. deferred
  292. ensure
  293. Result >= 0
  294. end
  295. fast_occurrences (elt: E_): INTEGER
  296. -- Number of occurrences using `='.
  297. -- See also `occurrences' to chose the appropriate one.
  298. deferred
  299. ensure
  300. Result >= 0
  301. end
  302. has (x: like item): BOOLEAN
  303. -- Search if a element x is in the array using `is_equal'.
  304. -- See also `fast_has' to chose the appropriate one.
  305. deferred
  306. end
  307. fast_has (x: like item): BOOLEAN
  308. -- Search if a element x is in the array using `='.
  309. deferred
  310. end
  311. replace_all (old_value, new_value: like item)
  312. -- Replace all occurrences of the element `old_value' by `new_value'
  313. -- using `is_equal' for comparison.
  314. -- See also `fast_replace_all' to choose the appropriate one.
  315. deferred
  316. ensure
  317. count = old count
  318. occurrences(old_value) = 0
  319. end
  320. fast_replace_all (old_value, new_value: like item)
  321. -- Replace all occurrences of the element `old_value' by `new_value'
  322. -- using operator `=' for comparison.
  323. -- See also `replace_all' to choose the appropriate one.
  324. deferred
  325. ensure
  326. count = old count
  327. fast_occurrences(old_value) = 0
  328. end
  329. sub_collection2 (line_min, line_max, column_min, column_max: INTEGER): like Current
  330. -- Create a new object using selected area of `Current'.
  331. require
  332. valid_index(line_min, column_min)
  333. valid_index(line_max, column_max)
  334. line_min <= line_max + 1
  335. column_min <= column_max + 1
  336. deferred
  337. ensure
  338. Result /= Void
  339. end
  340. set_area (element: like item; line_min, line_max, column_min, column_max: INTEGER)
  341. -- Set all the elements of the selected area rectangle with `element'.
  342. require
  343. valid_index(line_min, column_min)
  344. valid_index(line_max, column_max)
  345. local
  346. line, column: INTEGER
  347. do
  348. from
  349. line := line_min
  350. until
  351. line > line_max
  352. loop
  353. from
  354. column := column_min
  355. until
  356. column > column_max
  357. loop
  358. put(element, line, column)
  359. column := column + 1
  360. end
  361. line := line + 1
  362. end
  363. ensure
  364. count = old count
  365. end
  366. feature {} -- Implement manifest generic creation:
  367. manifest_put (index: INTEGER; element: like item)
  368. require
  369. index >= 0
  370. deferred
  371. end
  372. manifest_semicolon_check: BOOLEAN True
  373. -- You can use semicolons to make the end of each line more visible.
  374. end -- class COLLECTION2
  375. --
  376. -- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
  377. --
  378. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  379. -- of this software and associated documentation files (the "Software"), to deal
  380. -- in the Software without restriction, including without limitation the rights
  381. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  382. -- copies of the Software, and to permit persons to whom the Software is
  383. -- furnished to do so, subject to the following conditions:
  384. --
  385. -- The above copyright notice and this permission notice shall be included in
  386. -- all copies or substantial portions of the Software.
  387. --
  388. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  389. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  390. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  391. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  392. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  393. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  394. -- THE SOFTWARE.