/src/wrappers/glib/partially-implemented/g_tree.e

http://github.com/tybor/Liberty · Specman e · 448 lines · 216 code · 73 blank · 159 comment · 6 complexity · bc5895ad0e6ac833a605ba298c9f27af MD5 · raw file

  1. indexing
  2. description: "Balanced Binary Trees, a sorted collection of key/value pairs optimized for searching and traversing in order."
  3. copyright: "[
  4. Copyright (C) 2005,2007 Paolo Redaelli, Glib team
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License
  7. as published by the Free Software Foundation; either version 2.1 of
  8. the License, or (at your option) any later version.
  9. This library is distributed in the hopeOA that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301 USA
  17. ]"
  18. license: "LGPL v2 or later"
  19. class G_TREE [VALUE->SHARED_C_STRUCT, KEY->COMPARABLE_SHARED_C_STRUCT]
  20. -- A sorted collection of key/value pairs optimized for searching
  21. -- and traversing in order.
  22. inherit
  23. DICTIONARY[VALUE, KEY]
  24. undefine
  25. is_equal, copy -- using the definition given by SHARED_C_STRUCT
  26. redefine
  27. get_new_iterator_on_items,
  28. manifest_make,
  29. do_all, for_all, exists
  30. end
  31. SHARED_C_STRUCT redefine dispose end
  32. insert
  33. G_TREE_EXTERNALS
  34. -- GLIB_TYPE_CONVERSION_MACROS -- Temporary
  35. creation with_comparer, from_external_pointer
  36. feature {} -- Creation
  37. make (a_key_factory: CACHING_FACTORY[KEY]; a_value_factory: CACHING_FACTORY[VALUE]) is
  38. -- Creates a new G_TREE; comparison is made using KEY's
  39. -- `compare' feature.
  40. require
  41. key_factory_not_void: a_key_factory/=Void
  42. value_factory_not_void: a_value_factory/=Void
  43. do
  44. key_factory := a_key_factory
  45. value_factory := a_value_factory
  46. create comparator.make(agent {KEY}.compare)
  47. from_external_pointer(g_tree_new_with_data
  48. (comparator.callback_address,
  49. comparator.to_pointer))
  50. end
  51. with_comparer (a_comparison_function: FUNCTION[ANY,TUPLE[KEY,KEY],INTEGER];
  52. a_key_factory: CACHING_FACTORY[KEY]; a_value_factory: CACHING_FACTORY[VALUE]) is
  53. -- Creates a new GTree.
  54. require
  55. comparison_function_not_void: a_comparison_function /= Void
  56. key_factory_not_void: a_key_factory/=Void
  57. value_factory_not_void: a_value_factory/=Void
  58. do
  59. create comparator.make (a_comparison_function)
  60. from_external_pointer(g_tree_new_with_data
  61. (comparator.callback_address,
  62. comparator.to_pointer))
  63. end
  64. -- TODO: if necessary g_tree_new_full ()
  65. -- GTree* g_tree_new_full (GCompareDataFunc key_compare_func,
  66. -- gpointer key_compare_data, GDestroyNotify key_destroy_func,
  67. -- GDestroyNotify value_destroy_func);
  68. -- Creates a new GTree like g_tree_new() and allows to specify
  69. -- functions to free the memory allocated for the key and value
  70. -- that get called when removing the entry from the GTree.
  71. -- key_compare_func : qsort()-style comparison function.
  72. -- key_compare_data : data to pass to comparison function.
  73. -- key_destroy_func : a function to free the memory allocated for the key used when removing the entry from the GTree or NULL if you don't want to supply such a function.
  74. -- value_destroy_func : a function to free the memory allocated for the value used when removing the entry from the GTree or NULL if you don't want to supply such a function.
  75. -- Returns : a new GTree.
  76. feature {ANY} -- Basic access:
  77. has (a_key: KEY): BOOLEAN is
  78. -- Is there a value currently associated with `a_key'?
  79. -- See also `fast_has', `at'.
  80. do
  81. if (g_tree_lookup(handle,a_key.handle)).is_not_null
  82. then Result:=True
  83. end
  84. end
  85. at (a_key: KEY): VALUE is
  86. -- The value associated to `a_key'.
  87. -- See also `fast_at', `reference_at', `has'.
  88. local p: POINTER
  89. do
  90. p:=g_tree_lookup(handle, a_key.handle)
  91. check require_has_key_implies_result_pointer_not_null:
  92. p.is_not_null
  93. end
  94. Result:=value_factory.wrapper(p)
  95. end
  96. reference_at (a_key: KEY): VALUE is
  97. -- the value corresponding to `a_key'. Since a GTree is
  98. -- automatically balanced as key/value pairs are added, key
  99. -- lookup is very fast.
  100. -- Void if `a_key' was not found.
  101. local p: POINTER; r: WRAPPER_RETRIEVER[VALUE]
  102. do
  103. p:=g_tree_lookup(handle, a_key.handle)
  104. if p.is_not_null then
  105. Result:=value_wrapper.wrapper(p)
  106. end
  107. end
  108. fast_has (a_key: KEY): BOOLEAN is
  109. -- Is there a value currently associated with `a_key'?
  110. -- Using basic `=' for comparison.
  111. --
  112. -- See also `has', `at', `fast_at'.
  113. do
  114. debug print_no_fast_notice; print (fast_fallback_notice) end
  115. Result:=has(a_key)
  116. end
  117. fast_at (a_key: KEY): VALUE is
  118. -- Return the value associated to key `k' using basic `=' for comparison.
  119. --
  120. -- See also `at', `reference_at', `fast_reference_at'.
  121. do
  122. debug print_no_fast_notice; print (fast_fallback_notice) end
  123. Result:=at(a_key)
  124. end
  125. fast_reference_at (a_key: KEY): VALUE is
  126. -- Same work as `reference_at', but basic `=' is used for comparison.
  127. --
  128. -- See also `reference_at', `at', `has'.
  129. do
  130. debug print_no_fast_notice; print (fast_fallback_notice) end
  131. Result:=reference_at(a_key)
  132. end
  133. feature {ANY}
  134. put (a_value: VALUE; a_key: KEY) is
  135. -- Change some existing entry or `add' the new one. If an entry with `a_key' is not yet in the dictionary,
  136. -- enter it with `a_value'. Otherwise overwrite the item associated with `a_key'.
  137. --
  138. -- The tree is automatically 'balanced' as new key/value
  139. -- pairs are added, so that the distance from the root to
  140. -- every leaf is as small as possible.
  141. require else value_not_void: a_value/=Void
  142. do
  143. -- TODO: Eiffelize this: If you supplied a value_destroy_func
  144. -- when creating the GTree, the old value is freed using that
  145. -- function. If you supplied a key_destroy_func when creating
  146. -- the GTree, the passed key is freed using that function.
  147. g_tree_insert(handle, a_key.handle, a_value.handle)
  148. end
  149. fast_put (a_value: VALUE; a_key: KEY) is
  150. -- Same job as `put', but uses basic `=' for comparison.
  151. --
  152. -- See also `put', `add'.
  153. do
  154. debug print_no_fast_notice; print (fast_fallback_notice) end
  155. put(a_value,a_key)
  156. end
  157. add (a_value: VALUE; a_key: KEY) is
  158. -- To add a new entry `k' with its associated value `v'.
  159. -- Actually, this is equivalent to call `put', but it may run a little bit faster.
  160. --
  161. -- See also `put', `fast_put'.
  162. do
  163. debug print_add_fallback end
  164. put(a_value,a_key)
  165. end
  166. feature {ANY} -- Removing:
  167. remove (a_key: KEY) is
  168. -- Remove entry `a_key' (which may exist or not before this call).
  169. -- As the `remove' procedure actually uses `is_equal', you may consider to use `fast_remove' for expanded
  170. -- objects as well while trying to get the very best performances.
  171. --
  172. -- See also `fast_remove', `clear_count'.
  173. local a_result: INTEGER
  174. do
  175. a_result:=g_tree_steal(handle,a_key.handle)
  176. -- Note: g_tree_steal removes a key and its associated value
  177. -- from a GTree without calling the key and value destroy
  178. -- functions.
  179. -- a_result is True(1) if the key was found (prior to 2.8,
  180. -- this function returned nothing)
  181. -- TODO: see if the following informations have some
  182. -- relevance for Eiffel. We could use g_tree_remove in case
  183. -- of particular cases of memory handling. Infact using
  184. -- g_tree_remove the following applies: If the GTree was
  185. -- created using g_tree_new_full(), the key and value are
  186. -- freed using the supplied destroy functions, otherwise you
  187. -- have to make sure that any dynamically allocated values
  188. -- are freed yourself. If the key does not exist in the
  189. -- GTree, the function does nothing.
  190. end
  191. fast_remove (a_key: KEY) is
  192. -- Same job as `remove', but uses basic `=' for comparison.
  193. --
  194. -- See also `remove', `clear_count'.
  195. do
  196. debug print_no_fast_notice; print (fast_fallback_notice) end
  197. remove (a_key)
  198. end
  199. clear_count is
  200. -- Discard all items (`is_empty' is True after that call). The internal `capacity' is not changed
  201. -- by this call.
  202. --
  203. -- See also `clear_count_and_capacity', `remove'.
  204. do
  205. not_yet_implemented
  206. end
  207. clear_count_and_capacity is
  208. -- Discard all items (`is_empty' is True after that call). The internal `capacity' may also be
  209. -- reduced after this call.
  210. --
  211. -- See also `clear_count', `remove'.
  212. do
  213. dispose -- and reallocate
  214. from_external_pointer(g_tree_new_with_data
  215. (comparator.callback_address, comparator.to_pointer))
  216. end
  217. capacity: INTEGER is
  218. -- Approximation of the actual internal storage `capacity'. The `capacity' will grow automatically
  219. -- when needed (i.e. `capacity' is not a limit for the number of values stored). Also note that
  220. -- the `capacity' value may not be always accurate depending of the implementation (anyway, this
  221. -- `capacity' value is at least equals to `count').
  222. do
  223. -- Note: implemented to be equal to count
  224. Result:=count
  225. end
  226. feature -- counting
  227. count: INTEGER_32 is
  228. do
  229. Result:=g_tree_nnodes(handle)
  230. end
  231. feature {ANY} -- To provide iterating facilities:
  232. item (index: INTEGER): VALUE is
  233. do
  234. not_yet_implemented
  235. end
  236. key (index: INTEGER): KEY is
  237. do
  238. not_yet_implemented
  239. end
  240. get_new_iterator_on_items: ITERATOR[VALUE] is
  241. do
  242. not_yet_implemented
  243. end
  244. get_new_iterator_on_keys: ITERATOR[KEY] is
  245. do
  246. not_yet_implemented
  247. end
  248. feature {ANY} -- Agents based features:
  249. do_all (action: ROUTINE[TUPLE[VALUE, KEY]]) is
  250. -- Apply `action' to every [VALUE, KEY] associations of `Current'.
  251. --
  252. -- See also `for_all', `exist'.
  253. do
  254. not_yet_implemented
  255. end
  256. for_all (test: PREDICATE[TUPLE[VALUE, KEY]]): BOOLEAN is
  257. -- Do all [VALUE, KEY] associations satisfy `test'?
  258. --
  259. -- See also `do_all', `exist'.
  260. -- local callback: G_TRAVERSE_CALLBACK
  261. do
  262. not_yet_implemented
  263. -- create callback.make a_test)
  264. -- g_tree_foreach (handle, callback.low_level_callback, $callback)
  265. end
  266. exists (test: PREDICATE[TUPLE[VALUE, KEY]]): BOOLEAN is
  267. do
  268. not_yet_implemented
  269. end
  270. feature {ANY} -- Other features:
  271. internal_key (a_key: KEY): KEY is
  272. -- Retrieve the internal key object which correspond to the existing
  273. -- entry `a_key' (the one memorized into the `Current' dictionary).
  274. --
  275. -- See also `has', `fast_has'.
  276. do
  277. not_yet_implemented
  278. end
  279. feature {} -- Implement manifest generic creation:
  280. manifest_make (needed_capacity: INTEGER) is
  281. -- Manifest creation of a dictionary.
  282. do
  283. not_yet_implemented
  284. end
  285. feature
  286. height: INTEGER is
  287. -- The height of a G_TREE.
  288. -- If the G_TREE contains no nodes, the height is 0. If the
  289. -- G_TREE contains only one root node the height is 1. If the
  290. -- root node has children the height is 2, etc.
  291. do
  292. Result:=g_tree_height(handle)
  293. end
  294. -- g_tree_search ()
  295. -- gpointer g_tree_search (GTree *tree,
  296. -- GCompareFunc search_func,
  297. -- gconstpointer user_data);
  298. -- Searches a GTree using search_func.
  299. -- The search_func is called with a pointer to the key of a key/value pair in the tree, and the passed in user_data. If search_func returns 0 for a key/value pair, then g_tree_search_func() will return the value of that pair. If search_func returns -1, searching will proceed among the key/value pairs that have a smaller key; if search_func returns 1, searching will proceed among the key/value pairs that have a larger key.
  300. -- tree : a GTree.
  301. -- search_func : a function used to search the GTree.
  302. -- user_data : the data passed as the second argument to the search_func function.
  303. -- Returns : the value corresponding to the found key, or NULL if the key was not found.
  304. dispose is
  305. -- Destroys the GTree.
  306. -- TODO: The following should held only for C; check
  307. -- it... "If keys and/or values are dynamically allocated,
  308. -- you should either free them first or create the GTree
  309. -- using g_tree_new_full(). In the latter case the destroy
  310. -- functions you supplied will be called on all keys and
  311. -- values before destroying the GTree"
  312. do
  313. g_tree_destroy(handle)
  314. handle:=default_pointer
  315. end
  316. compare (a_value, another_value: VALUE): INTEGER is
  317. -- The comparison function of two values. The function should
  318. -- return a negative integer if the first value comes before
  319. -- the second, 0 if they are equal, or a positive integer if
  320. -- the first value comes after the second.
  321. obsolete "Work in progress on callbacks"
  322. do
  323. end
  324. feature {} -- Low level implementation
  325. comparator: G_COMPARE_DATA_CALLBACK [KEY]
  326. -- The object containing the callback that will be called by C
  327. key_factory: WRAPPER_FACTORY[KEY]
  328. value_factory: WRAPPER_FACTORY[VALUE]
  329. print_no_fast_notice is
  330. once
  331. print(no_fast_notice)
  332. end
  333. no_fast_notice: STRING is
  334. "Original C GTree implementation does not offer functions equivalent to `fast_has,' `fast_at', `fast_reference_at', `fast_put' and `fast_remove'. An eventual implementation of those features would require to manipulate directly GTree data-structure, skipping the Glib abstraction. Paolo 2007-07-15%N"
  335. fast_fallback_notice: STRING is
  336. "Fast_[has|at|reference_at|put] feature not available. Falling back to non-fast features.%N"
  337. print_add_fallback is
  338. once
  339. print (print_add_fallback_notice)
  340. end
  341. print_add_fallback_notice: STRING is
  342. "Original C GTree implementation does not offer a function equivalent to `add'. Falling back to `put' feature. Paolo 2007-07-15%N"
  343. feature {} -- Unwrapped code
  344. -- TODO: it is necessary to wrap g_tree_lookup_extended ?
  345. -- gboolean g_tree_lookup_extended (GTree *tree, gconstpointer
  346. -- lookup_key, gpointer *orig_key, gpointer *value);
  347. -- Looks up a key in the GTree, returning the original key and the
  348. -- associated value and a gboolean which is TRUE if the key was
  349. -- found. This is useful if you need to free the memory allocated
  350. -- for the original key, for example before calling
  351. -- g_tree_remove().
  352. -- tree : a GTree.
  353. -- lookup_key : the key to look up.
  354. -- orig_key : returns the original key.
  355. -- value : returns the value associated with the key.
  356. -- Returns : TRUE if the key was found in the GTree.
  357. -- AFAIK wrapping replace is just not necessary in Eiffel
  358. -- replace (a_key: KEY; a_value: VALUE) is
  359. -- -- Inserts `a_key' and `a_value' into a GTree similar to
  360. -- -- `insert_value'. The difference is that if `a_key' already
  361. -- -- exists in the GTree, it gets replaced by the new key. If
  362. -- -- you supplied a value_destroy_func when creating the GTree,
  363. -- -- the old value is freed using that function. If you
  364. -- -- supplied a key_destroy_func when creating the GTree, the
  365. -- -- old key is freed using that function.
  366. -- -- The tree is automatically 'balanced' as new key/value
  367. -- -- pairs are added, so that the distance from the root to
  368. -- -- every leaf is as small as possible.
  369. -- require
  370. -- key_not_void: a_key/=Void
  371. -- value_not_void: a_value/=Void
  372. -- do
  373. -- g_tree_replace(handle,a_key.handle,a_value.handle)
  374. -- end
  375. end