免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 14575 | 回复: 20
打印 上一主题 下一主题

[C] 有没有c语言版的tuple, list, vector, hash等通用数据结构的实现? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-04 15:41 |只看该作者 |倒序浏览
有没有c语言版的tuple, list, vector, hash等通用数据结构的实现?

谢谢!

论坛徽章:
0
2 [报告]
发表于 2008-06-04 16:53 |只看该作者
glib

论坛徽章:
0
3 [报告]
发表于 2008-06-04 16:59 |只看该作者
list和hash 在kernel中有做好的可以截出来用。

论坛徽章:
0
4 [报告]
发表于 2008-06-04 17:05 |只看该作者
找一本教材一看看吧.

论坛徽章:
0
5 [报告]
发表于 2008-06-04 18:17 |只看该作者
用c++啊

论坛徽章:
0
6 [报告]
发表于 2008-06-04 22:35 |只看该作者
前段时间从 Linux kernel 中提取的一个 list.h,刚好给楼主参考一下。



  1. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  2. #define container_of(ptr, type, member) ({ \
  3.         const typeof( ((type *)0)->member) *__mptr = (ptr); \
  4.         (type *)( (char *)__mptr - offsetof(type, member) );})

  5. #define LIST_POISON1 ((void *) 0x00100100)
  6. #define LIST_POISON2 ((void *) 0x00200200)

  7. static inline void prefetch(const void *x) {;}
  8. static inline void prefetchw(const void *x) {;}
  9. /*
  10. * Simple doubly linked list implementation.
  11. *
  12. * Some of the internal functions ("__xxx") are useful when
  13. * manipulating whole lists rather than single entries, as
  14. * sometimes we already know the next/prev entries and we can
  15. * generate better code by using them directly rather than
  16. * using the generic single-entry routines.
  17. */

  18. struct list_head {
  19.         struct list_head *next, *prev;
  20. };

  21. #define LIST_HEAD_INIT(name) { &(name), &(name) }

  22. #define LIST_HEAD(name) \
  23.         struct list_head name = LIST_HEAD_INIT(name)

  24. static inline void INIT_LIST_HEAD(struct list_head *list)
  25. {
  26.         list->next = list;
  27.         list->prev = list;
  28. }

  29. /*
  30. * Insert a new entry between two known consecutive entries.
  31. *
  32. * This is only for internal list manipulation where we know
  33. * the prev/next entries already!
  34. */
  35. static inline void __list_add(struct list_head *new,
  36.                               struct list_head *prev,
  37.                               struct list_head *next)
  38. {
  39.         next->prev = new;
  40.         new->next = next;
  41.         new->prev = prev;
  42.         prev->next = new;
  43. }

  44. /**
  45. * list_add - add a new entry
  46. * @new: new entry to be added
  47. * @head: list head to add it after
  48. *
  49. * Insert a new entry after the specified head.
  50. * This is good for implementing stacks.
  51. */
  52. static inline void list_add(struct list_head *new, struct list_head *head)
  53. {
  54.         __list_add(new, head, head->next);
  55. }


  56. /**
  57. * list_add_tail - add a new entry
  58. * @new: new entry to be added
  59. * @head: list head to add it before
  60. *
  61. * Insert a new entry before the specified head.
  62. * This is useful for implementing queues.
  63. */
  64. static inline void list_add_tail(struct list_head *new, struct list_head *head)
  65. {
  66.         __list_add(new, head->prev, head);
  67. }



  68. /*
  69. * Delete a list entry by making the prev/next entries
  70. * point to each other.
  71. *
  72. * This is only for internal list manipulation where we know
  73. * the prev/next entries already!
  74. */
  75. static inline void __list_del(struct list_head * prev, struct list_head * next)
  76. {
  77.         next->prev = prev;
  78.         prev->next = next;
  79. }

  80. /**
  81. * list_del - deletes entry from list.
  82. * @entry: the element to delete from the list.
  83. * Note: list_empty on entry does not return true after this, the entry is
  84. * in an undefined state.
  85. */
  86. static inline void list_del(struct list_head *entry)
  87. {
  88.         __list_del(entry->prev, entry->next);
  89.         entry->next = LIST_POISON1;
  90.         entry->prev = LIST_POISON2;
  91. }


  92. /**
  93. * list_replace - replace old entry by new one
  94. * @old : the element to be replaced
  95. * @new : the new element to insert
  96. * Note: if 'old' was empty, it will be overwritten.
  97. */
  98. static inline void list_replace(struct list_head *old,
  99.                                 struct list_head *new)
  100. {
  101.         new->next = old->next;
  102.         new->next->prev = new;
  103.         new->prev = old->prev;
  104.         new->prev->next = new;
  105. }

  106. static inline void list_replace_init(struct list_head *old,
  107.                                         struct list_head *new)
  108. {
  109.         list_replace(old, new);
  110.         INIT_LIST_HEAD(old);
  111. }


  112. /**
  113. * list_del_init - deletes entry from list and reinitialize it.
  114. * @entry: the element to delete from the list.
  115. */
  116. static inline void list_del_init(struct list_head *entry)
  117. {
  118.         __list_del(entry->prev, entry->next);
  119.         INIT_LIST_HEAD(entry);
  120. }

  121. /**
  122. * list_move - delete from one list and add as another's head
  123. * @list: the entry to move
  124. * @head: the head that will precede our entry
  125. */
  126. static inline void list_move(struct list_head *list, struct list_head *head)
  127. {
  128.         __list_del(list->prev, list->next);
  129.         list_add(list, head);
  130. }

  131. /**
  132. * list_move_tail - delete from one list and add as another's tail
  133. * @list: the entry to move
  134. * @head: the head that will follow our entry
  135. */
  136. static inline void list_move_tail(struct list_head *list,
  137.                                   struct list_head *head)
  138. {
  139.         __list_del(list->prev, list->next);
  140.         list_add_tail(list, head);
  141. }

  142. /**
  143. * list_is_last - tests whether @list is the last entry in list @head
  144. * @list: the entry to test
  145. * @head: the head of the list
  146. */
  147. static inline int list_is_last(const struct list_head *list,
  148.                                 const struct list_head *head)
  149. {
  150.         return list->next == head;
  151. }

  152. /**
  153. * list_empty - tests whether a list is empty
  154. * @head: the list to test.
  155. */
  156. static inline int list_empty(const struct list_head *head)
  157. {
  158.         return head->next == head;
  159. }

  160. /**
  161. * list_empty_careful - tests whether a list is empty and not being modified
  162. * @head: the list to test
  163. *
  164. * Description:
  165. * tests whether a list is empty _and_ checks that no other CPU might be
  166. * in the process of modifying either member (next or prev)
  167. *
  168. * NOTE: using list_empty_careful() without synchronization
  169. * can only be safe if the only activity that can happen
  170. * to the list entry is list_del_init(). Eg. it cannot be used
  171. * if another CPU could re-list_add() it.
  172. */
  173. static inline int list_empty_careful(const struct list_head *head)
  174. {
  175.         struct list_head *next = head->next;
  176.         return (next == head) && (next == head->prev);
  177. }

  178. static inline void __list_splice(struct list_head *list,
  179.                                  struct list_head *head)
  180. {
  181.         struct list_head *first = list->next;
  182.         struct list_head *last = list->prev;
  183.         struct list_head *at = head->next;

  184.         first->prev = head;
  185.         head->next = first;

  186.         last->next = at;
  187.         at->prev = last;
  188. }

  189. /**
  190. * list_splice - join two lists
  191. * @list: the new list to add.
  192. * @head: the place to add it in the first list.
  193. */
  194. static inline void list_splice(struct list_head *list, struct list_head *head)
  195. {
  196.         if (!list_empty(list))
  197.                 __list_splice(list, head);
  198. }

  199. /**
  200. * list_splice_init - join two lists and reinitialise the emptied list.
  201. * @list: the new list to add.
  202. * @head: the place to add it in the first list.
  203. *
  204. * The list at @list is reinitialised
  205. */
  206. static inline void list_splice_init(struct list_head *list,
  207.                                     struct list_head *head)
  208. {
  209.         if (!list_empty(list)) {
  210.                 __list_splice(list, head);
  211.                 INIT_LIST_HEAD(list);
  212.         }
  213. }


  214. /**
  215. * list_entry - get the struct for this entry
  216. * @ptr:        the &struct list_head pointer.
  217. * @type:        the type of the struct this is embedded in.
  218. * @member:        the name of the list_struct within the struct.
  219. */
  220. #define list_entry(ptr, type, member) \
  221.         container_of(ptr, type, member)

  222. /**
  223. * list_for_each        -        iterate over a list
  224. * @pos:        the &struct list_head to use as a loop cursor.
  225. * @head:        the head for your list.
  226. */
  227. #define list_for_each(pos, head) \
  228.         for (pos = (head)->next; prefetch(pos->next), pos != (head); \
  229.                 pos = pos->next)

  230. /**
  231. * __list_for_each        -        iterate over a list
  232. * @pos:        the &struct list_head to use as a loop cursor.
  233. * @head:        the head for your list.
  234. *
  235. * This variant differs from list_for_each() in that it's the
  236. * simplest possible list iteration code, no prefetching is done.
  237. * Use this for code that knows the list to be very short (empty
  238. * or 1 entry) most of the time.
  239. */
  240. #define __list_for_each(pos, head) \
  241.         for (pos = (head)->next; pos != (head); pos = pos->next)

  242. /**
  243. * list_for_each_prev        -        iterate over a list backwards
  244. * @pos:        the &struct list_head to use as a loop cursor.
  245. * @head:        the head for your list.
  246. */
  247. #define list_for_each_prev(pos, head) \
  248.         for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
  249.                 pos = pos->prev)

  250. /**
  251. * list_for_each_safe - iterate over a list safe against removal of list entry
  252. * @pos:        the &struct list_head to use as a loop cursor.
  253. * @n:                another &struct list_head to use as temporary storage
  254. * @head:        the head for your list.
  255. */
  256. #define list_for_each_safe(pos, n, head) \
  257.         for (pos = (head)->next, n = pos->next; pos != (head); \
  258.                 pos = n, n = pos->next)

  259. /**
  260. * list_for_each_entry        -        iterate over list of given type
  261. * @pos:        the type * to use as a loop cursor.
  262. * @head:        the head for your list.
  263. * @member:        the name of the list_struct within the struct.
  264. */
  265. #define list_for_each_entry(pos, head, member)                                \
  266.         for (pos = list_entry((head)->next, typeof(*pos), member);        \
  267.              prefetch(pos->member.next), &pos->member != (head);         \
  268.              pos = list_entry(pos->member.next, typeof(*pos), member))

  269. /**
  270. * list_for_each_entry_reverse - iterate backwards over list of given type.
  271. * @pos:        the type * to use as a loop cursor.
  272. * @head:        the head for your list.
  273. * @member:        the name of the list_struct within the struct.
  274. */
  275. #define list_for_each_entry_reverse(pos, head, member)                        \
  276.         for (pos = list_entry((head)->prev, typeof(*pos), member);        \
  277.              prefetch(pos->member.prev), &pos->member != (head);         \
  278.              pos = list_entry(pos->member.prev, typeof(*pos), member))

  279. /**
  280. * list_prepare_entry - prepare a pos entry for use in
  281. * list_for_each_entry_continue
  282. * @pos:        the type * to use as a start point
  283. * @head:        the head of the list
  284. * @member:        the name of the list_struct within the struct.
  285. *
  286. * Prepares a pos entry for use as a start point in
  287. * list_for_each_entry_continue.
  288. */
  289. #define list_prepare_entry(pos, head, member) \
  290.         ((pos) ? : list_entry(head, typeof(*pos), member))

  291. /**
  292. * list_for_each_entry_continue - continue iteration over list of given type
  293. * @pos:        the type * to use as a loop cursor.
  294. * @head:        the head for your list.
  295. * @member:        the name of the list_struct within the struct.
  296. *
  297. * Continue to iterate over list of given type, continuing after
  298. * the current position.
  299. */
  300. #define list_for_each_entry_continue(pos, head, member)                 \
  301.         for (pos = list_entry(pos->member.next, typeof(*pos), member);        \
  302.              prefetch(pos->member.next), &pos->member != (head);        \
  303.              pos = list_entry(pos->member.next, typeof(*pos), member))

  304. /**
  305. * list_for_each_entry_from - iterate over list of given type from the
  306. * current point
  307. * @pos:        the type * to use as a loop cursor.
  308. * @head:        the head for your list.
  309. * @member:        the name of the list_struct within the struct.
  310. *
  311. * Iterate over list of given type, continuing from current position.
  312. */
  313. #define list_for_each_entry_from(pos, head, member)                         \
  314.         for (; prefetch(pos->member.next), &pos->member != (head);        \
  315.              pos = list_entry(pos->member.next, typeof(*pos), member))

  316. /**
  317. * list_for_each_entry_safe - iterate over list of given type safe against
  318. * removal of list entry
  319. * @pos:        the type * to use as a loop cursor.
  320. * @n:                another type * to use as temporary storage
  321. * @head:        the head for your list.
  322. * @member:        the name of the list_struct within the struct.
  323. */
  324. #define list_for_each_entry_safe(pos, n, head, member)                        \
  325.         for (pos = list_entry((head)->next, typeof(*pos), member),        \
  326.                 n = list_entry(pos->member.next, typeof(*pos), member);        \
  327.              &pos->member != (head);                                         \
  328.              pos = n, n = list_entry(n->member.next, typeof(*n), member))

  329. /**
  330. * list_for_each_entry_safe_continue
  331. * @pos:        the type * to use as a loop cursor.
  332. * @n:                another type * to use as temporary storage
  333. * @head:        the head for your list.
  334. * @member:        the name of the list_struct within the struct.
  335. *
  336. * Iterate over list of given type, continuing after current point,
  337. * safe against removal of list entry.
  338. */
  339. #define list_for_each_entry_safe_continue(pos, n, head, member)                 \
  340.         for (pos = list_entry(pos->member.next, typeof(*pos), member),                 \
  341.                 n = list_entry(pos->member.next, typeof(*pos), member);                \
  342.              &pos->member != (head);                                                \
  343.              pos = n, n = list_entry(n->member.next, typeof(*n), member))

  344. /**
  345. * list_for_each_entry_safe_from
  346. * @pos:        the type * to use as a loop cursor.
  347. * @n:                another type * to use as temporary storage
  348. * @head:        the head for your list.
  349. * @member:        the name of the list_struct within the struct.
  350. *
  351. * Iterate over list of given type from current point, safe against
  352. * removal of list entry.
  353. */
  354. #define list_for_each_entry_safe_from(pos, n, head, member)                         \
  355.         for (n = list_entry(pos->member.next, typeof(*pos), member);                \
  356.              &pos->member != (head);                                                \
  357.              pos = n, n = list_entry(n->member.next, typeof(*n), member))

  358. /**
  359. * list_for_each_entry_safe_reverse
  360. * @pos:        the type * to use as a loop cursor.
  361. * @n:                another type * to use as temporary storage
  362. * @head:        the head for your list.
  363. * @member:        the name of the list_struct within the struct.
  364. *
  365. * Iterate backwards over list of given type, safe against removal
  366. * of list entry.
  367. */
  368. #define list_for_each_entry_safe_reverse(pos, n, head, member)                \
  369.         for (pos = list_entry((head)->prev, typeof(*pos), member),        \
  370.                 n = list_entry(pos->member.prev, typeof(*pos), member);        \
  371.              &pos->member != (head);                                         \
  372.              pos = n, n = list_entry(n->member.prev, typeof(*n), member))


  373. /*
  374. * Double linked lists with a single pointer list head.
  375. * Mostly useful for hash tables where the two pointer list head is
  376. * too wasteful.
  377. * You lose the ability to access the tail in O(1).
  378. */

  379. struct hlist_head {
  380.         struct hlist_node *first;
  381. };

  382. struct hlist_node {
  383.         struct hlist_node *next, **pprev;
  384. };

  385. #define HLIST_HEAD_INIT { .first = NULL }
  386. #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
  387. #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
  388. static inline void INIT_HLIST_NODE(struct hlist_node *h)
  389. {
  390.         h->next = NULL;
  391.         h->pprev = NULL;
  392. }

  393. static inline int hlist_unhashed(const struct hlist_node *h)
  394. {
  395.         return !h->pprev;
  396. }

  397. static inline int hlist_empty(const struct hlist_head *h)
  398. {
  399.         return !h->first;
  400. }

  401. static inline void __hlist_del(struct hlist_node *n)
  402. {
  403.         struct hlist_node *next = n->next;
  404.         struct hlist_node **pprev = n->pprev;
  405.         *pprev = next;
  406.         if (next)
  407.                 next->pprev = pprev;
  408. }

  409. static inline void hlist_del(struct hlist_node *n)
  410. {
  411.         __hlist_del(n);
  412.         n->next = LIST_POISON1;
  413.         n->pprev = LIST_POISON2;
  414. }


  415. static inline void hlist_del_init(struct hlist_node *n)
  416. {
  417.         if (!hlist_unhashed(n)) {
  418.                 __hlist_del(n);
  419.                 INIT_HLIST_NODE(n);
  420.         }
  421. }


  422. static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
  423. {
  424.         struct hlist_node *first = h->first;
  425.         n->next = first;
  426.         if (first)
  427.                 first->pprev = &n->next;
  428.         h->first = n;
  429.         n->pprev = &h->first;
  430. }


  431. /* next must be != NULL */
  432. static inline void hlist_add_before(struct hlist_node *n,
  433.                                         struct hlist_node *next)
  434. {
  435.         n->pprev = next->pprev;
  436.         n->next = next;
  437.         next->pprev = &n->next;
  438.         *(n->pprev) = n;
  439. }

  440. static inline void hlist_add_after(struct hlist_node *n,
  441.                                         struct hlist_node *next)
  442. {
  443.         next->next = n->next;
  444.         n->next = next;
  445.         next->pprev = &n->next;

  446.         if(next->next)
  447.                 next->next->pprev  = &next->next;
  448. }


  449. #define hlist_entry(ptr, type, member) container_of(ptr,type,member)

  450. #define hlist_for_each(pos, head) \
  451.         for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
  452.              pos = pos->next)

  453. #define hlist_for_each_safe(pos, n, head) \
  454.         for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
  455.              pos = n)

  456. /**
  457. * hlist_for_each_entry        - iterate over list of given type
  458. * @tpos:        the type * to use as a loop cursor.
  459. * @pos:        the &struct hlist_node to use as a loop cursor.
  460. * @head:        the head for your list.
  461. * @member:        the name of the hlist_node within the struct.
  462. */
  463. #define hlist_for_each_entry(tpos, pos, head, member)                         \
  464.         for (pos = (head)->first;                                         \
  465.              pos && ({ prefetch(pos->next); 1;}) &&                         \
  466.                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  467.              pos = pos->next)

  468. /**
  469. * hlist_for_each_entry_continue - iterate over a hlist continuing after
  470. * current point
  471. * @tpos:        the type * to use as a loop cursor.
  472. * @pos:        the &struct hlist_node to use as a loop cursor.
  473. * @member:        the name of the hlist_node within the struct.
  474. */
  475. #define hlist_for_each_entry_continue(tpos, pos, member)                 \
  476.         for (pos = (pos)->next;                                                 \
  477.              pos && ({ prefetch(pos->next); 1;}) &&                         \
  478.                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  479.              pos = pos->next)

  480. /**
  481. * hlist_for_each_entry_from - iterate over a hlist continuing from
  482. * current point
  483. * @tpos:        the type * to use as a loop cursor.
  484. * @pos:        the &struct hlist_node to use as a loop cursor.
  485. * @member:        the name of the hlist_node within the struct.
  486. */
  487. #define hlist_for_each_entry_from(tpos, pos, member)                         \
  488.         for (; pos && ({ prefetch(pos->next); 1;}) &&                         \
  489.                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  490.              pos = pos->next)

  491. /**
  492. * hlist_for_each_entry_safe - iterate over list of given type safe
  493. * against removal of list entry
  494. * @tpos:        the type * to use as a loop cursor.
  495. * @pos:        the &struct hlist_node to use as a loop cursor.
  496. * @n:                another &struct hlist_node to use as temporary storage
  497. * @head:        the head for your list.
  498. * @member:        the name of the hlist_node within the struct.
  499. */
  500. #define hlist_for_each_entry_safe(tpos, pos, n, head, member)                  \
  501.         for (pos = (head)->first;                                         \
  502.              pos && ({ n = pos->next; 1; }) &&                                  \
  503.                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  504.              pos = n)

复制代码

论坛徽章:
0
7 [报告]
发表于 2008-06-05 08:35 |只看该作者
kernel 中的这个实现真是……
不知道怎么来形容了,奇特得令人发指。

论坛徽章:
0
8 [报告]
发表于 2008-06-05 09:08 |只看该作者
原帖由 drunkedcat 于 2008-6-5 08:35 发表
kernel 中的这个实现真是……
不知道怎么来形容了,奇特得令人发指。

内核中还有红黑树、基数树、堆排序等的实现,如果这个令人发指,那那些可就不知道怎么形容。

论坛徽章:
0
9 [报告]
发表于 2008-06-05 09:59 |只看该作者

回复 #7 drunkedcat 的帖子

????????

论坛徽章:
0
10 [报告]
发表于 2008-06-05 16:51 |只看该作者
原帖由 cugb_cat 于 2008-6-5 09:08 发表

内核中还有红黑树、基数树、堆排序等的实现,如果这个令人发指,那那些可就不知道怎么形容。


不好意思,误会了,我是说关于从一个结构中找到一个成员地址的方法,不是指 list 这个结构。

当时看了这段代码后,我就再也不敢在人前说我“熟悉” C 语言了。所以才说它“令人发指”。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP