typeof

Тема в разделе "LANGS.C", создана пользователем osox, 27 апр 2010.

  1. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Всех приветствую хотел адаптировать под свои нужды список из линукса (нужен в проекте на msvC) но вот незадача в половине макросов применяется typeof можно каждому макросу добавить параметр-тип тогда им можно будет заменить все typeof но в макросах и так по три параметра как сделать так чтоб это было меньшее из зол :)

    вот реализация списка list.h

    Код (Text):
    1.   1 #ifndef _LINUX_LIST_H
    2.   2 #define _LINUX_LIST_H
    3.   3
    4.   4 #include <linux/stddef.h>
    5.   5 #include <linux/poison.h>
    6.   6 #include <linux/prefetch.h>
    7.   7 #include <asm/system.h>
    8.   8
    9.   9 /*
    10.  10  * Simple doubly linked list implementation.
    11.  11  *
    12.  12  * Some of the internal functions ("__xxx") are useful when
    13.  13  * manipulating whole lists rather than single entries, as
    14.  14  * sometimes we already know the next/prev entries and we can
    15.  15  * generate better code by using them directly rather than
    16.  16  * using the generic single-entry routines.
    17.  17  */
    18.  18
    19.  19 struct list_head {
    20.  20         struct list_head *next, *prev;
    21.  21 };
    22.  22
    23.  23 #define LIST_HEAD_INIT(name) { &(name), &(name) }
    24.  24
    25.  25 #define LIST_HEAD(name) \
    26.  26         struct list_head name = LIST_HEAD_INIT(name)
    27.  27
    28.  28 static inline void INIT_LIST_HEAD(struct list_head *list)
    29.  29 {
    30.  30         list->next = list;
    31.  31         list->prev = list;
    32.  32 }
    33.  33
    34.  34 /*
    35.  35  * Insert a new entry between two known consecutive entries.
    36.  36  *
    37.  37  * This is only for internal list manipulation where we know
    38.  38  * the prev/next entries already!
    39.  39  */
    40.  40 #ifndef CONFIG_DEBUG_LIST
    41.  41 static inline void __list_add(struct list_head *new,
    42.  42                               struct list_head *prev,
    43.  43                               struct list_head *next)
    44.  44 {
    45.  45         next->prev = new;
    46.  46         new->next = next;
    47.  47         new->prev = prev;
    48.  48         prev->next = new;
    49.  49 }
    50.  50 #else
    51.  51 extern void __list_add(struct list_head *new,
    52.  52                               struct list_head *prev,
    53.  53                               struct list_head *next);
    54.  54 #endif
    55.  55
    56.  56 /**
    57.  57  * list_add - add a new entry
    58.  58  * @new: new entry to be added
    59.  59  * @head: list head to add it after
    60.  60  *
    61.  61  * Insert a new entry after the specified head.
    62.  62  * This is good for implementing stacks.
    63.  63  */
    64.  64 static inline void list_add(struct list_head *new, struct list_head *head)
    65.  65 {
    66.  66         __list_add(new, head, head->next);
    67.  67 }
    68.  68
    69.  69
    70.  70 /**
    71.  71  * list_add_tail - add a new entry
    72.  72  * @new: new entry to be added
    73.  73  * @head: list head to add it before
    74.  74  *
    75.  75  * Insert a new entry before the specified head.
    76.  76  * This is useful for implementing queues.
    77.  77  */
    78.  78 static inline void list_add_tail(struct list_head *new, struct list_head *head)
    79.  79 {
    80.  80         __list_add(new, head->prev, head);
    81.  81 }
    82.  82
    83.  83 /*
    84.  84  * Delete a list entry by making the prev/next entries
    85.  85  * point to each other.
    86.  86  *
    87.  87  * This is only for internal list manipulation where we know
    88.  88  * the prev/next entries already!
    89.  89  */
    90.  90 static inline void __list_del(struct list_head * prev, struct list_head * next)
    91.  91 {
    92.  92         next->prev = prev;
    93.  93         prev->next = next;
    94.  94 }
    95.  95
    96.  96 /**
    97.  97  * list_del - deletes entry from list.
    98.  98  * @entry: the element to delete from the list.
    99.  99  * Note: list_empty() on entry does not return true after this, the entry is
    100. 100  * in an undefined state.
    101. 101  */
    102. 102 #ifndef CONFIG_DEBUG_LIST
    103. 103 static inline void list_del(struct list_head *entry)
    104. 104 {
    105. 105         __list_del(entry->prev, entry->next);
    106. 106         entry->next = LIST_POISON1;
    107. 107         entry->prev = LIST_POISON2;
    108. 108 }
    109. 109 #else
    110. 110 extern void list_del(struct list_head *entry);
    111. 111 #endif
    112. 112
    113. 113 /**
    114. 114  * list_replace - replace old entry by new one
    115. 115  * @old : the element to be replaced
    116. 116  * @new : the new element to insert
    117. 117  *
    118. 118  * If @old was empty, it will be overwritten.
    119. 119  */
    120. 120 static inline void list_replace(struct list_head *old,
    121. 121                                 struct list_head *new)
    122. 122 {
    123. 123         new->next = old->next;
    124. 124         new->next->prev = new;
    125. 125         new->prev = old->prev;
    126. 126         new->prev->next = new;
    127. 127 }
    128. 128
    129. 129 static inline void list_replace_init(struct list_head *old,
    130. 130                                         struct list_head *new)
    131. 131 {
    132. 132         list_replace(old, new);
    133. 133         INIT_LIST_HEAD(old);
    134. 134 }
    135. 135
    136. 136 /**
    137. 137  * list_del_init - deletes entry from list and reinitialize it.
    138. 138  * @entry: the element to delete from the list.
    139. 139  */
    140. 140 static inline void list_del_init(struct list_head *entry)
    141. 141 {
    142. 142         __list_del(entry->prev, entry->next);
    143. 143         INIT_LIST_HEAD(entry);
    144. 144 }
    145. 145
    146. 146 /**
    147. 147  * list_move - delete from one list and add as another's head
    148. 148  * @list: the entry to move
    149. 149  * @head: the head that will precede our entry
    150. 150  */
    151. 151 static inline void list_move(struct list_head *list, struct list_head *head)
    152. 152 {
    153. 153         __list_del(list->prev, list->next);
    154. 154         list_add(list, head);
    155. 155 }
    156. 156
    157. 157 /**
    158. 158  * list_move_tail - delete from one list and add as another's tail
    159. 159  * @list: the entry to move
    160. 160  * @head: the head that will follow our entry
    161. 161  */
    162. 162 static inline void list_move_tail(struct list_head *list,
    163. 163                                   struct list_head *head)
    164. 164 {
    165. 165         __list_del(list->prev, list->next);
    166. 166         list_add_tail(list, head);
    167. 167 }
    168. 168
    169. 169 /**
    170. 170  * list_is_last - tests whether @list is the last entry in list @head
    171. 171  * @list: the entry to test
    172. 172  * @head: the head of the list
    173. 173  */
    174. 174 static inline int list_is_last(const struct list_head *list,
    175. 175                                 const struct list_head *head)
    176. 176 {
    177. 177         return list->next == head;
    178. 178 }
    179. 179
    180. 180 /**
    181. 181  * list_empty - tests whether a list is empty
    182. 182  * @head: the list to test.
    183. 183  */
    184. 184 static inline int list_empty(const struct list_head *head)
    185. 185 {
    186. 186         return head->next == head;
    187. 187 }
    188. 188
    189. 189 /**
    190. 190  * list_empty_careful - tests whether a list is empty and not being modified
    191. 191  * @head: the list to test
    192. 192  *
    193. 193  * Description:
    194. 194  * tests whether a list is empty _and_ checks that no other CPU might be
    195. 195  * in the process of modifying either member (next or prev)
    196. 196  *
    197. 197  * NOTE: using list_empty_careful() without synchronization
    198. 198  * can only be safe if the only activity that can happen
    199. 199  * to the list entry is list_del_init(). Eg. it cannot be used
    200. 200  * if another CPU could re-list_add() it.
    201. 201  */
    202. 202 static inline int list_empty_careful(const struct list_head *head)
    203. 203 {
    204. 204         struct list_head *next = head->next;
    205. 205         return (next == head) && (next == head->prev);
    206. 206 }
    207. 207
    208. 208 /**
    209. 209  * list_rotate_left - rotate the list to the left
    210. 210  * @head: the head of the list
    211. 211  */
    212. 212 static inline void list_rotate_left(struct list_head *head)
    213. 213 {
    214. 214         struct list_head *first;
    215. 215
    216. 216         if (!list_empty(head)) {
    217. 217                 first = head->next;
    218. 218                 list_move_tail(first, head);
    219. 219         }
    220. 220 }
    221. 221
    222. 222 /**
    223. 223  * list_is_singular - tests whether a list has just one entry.
    224. 224  * @head: the list to test.
    225. 225  */
    226. 226 static inline int list_is_singular(const struct list_head *head)
    227. 227 {
    228. 228         return !list_empty(head) && (head->next == head->prev);
    229. 229 }
    230. 230
    231. 231 static inline void __list_cut_position(struct list_head *list,
    232. 232                 struct list_head *head, struct list_head *entry)
    233. 233 {
    234. 234         struct list_head *new_first = entry->next;
    235. 235         list->next = head->next;
    236. 236         list->next->prev = list;
    237. 237         list->prev = entry;
    238. 238         entry->next = list;
    239. 239         head->next = new_first;
    240. 240         new_first->prev = head;
    241. 241 }
    242. 242
    243. 243 /**
    244. 244  * list_cut_position - cut a list into two
    245. 245  * @list: a new list to add all removed entries
    246. 246  * @head: a list with entries
    247. 247  * @entry: an entry within head, could be the head itself
    248. 248  *      and if so we won't cut the list
    249. 249  *
    250. 250  * This helper moves the initial part of @head, up to and
    251. 251  * including @entry, from @head to @list. You should
    252. 252  * pass on @entry an element you know is on @head. @list
    253. 253  * should be an empty list or a list you do not care about
    254. 254  * losing its data.
    255. 255  *
    256. 256  */
    257. 257 static inline void list_cut_position(struct list_head *list,
    258. 258                 struct list_head *head, struct list_head *entry)
    259. 259 {
    260. 260         if (list_empty(head))
    261. 261                 return;
    262. 262         if (list_is_singular(head) &&
    263. 263                 (head->next != entry && head != entry))
    264. 264                 return;
    265. 265         if (entry == head)
    266. 266                 INIT_LIST_HEAD(list);
    267. 267         else
    268. 268                 __list_cut_position(list, head, entry);
    269. 269 }
    270. 270
    271. 271 static inline void __list_splice(const struct list_head *list,
    272. 272                                  struct list_head *prev,
    273. 273                                  struct list_head *next)
    274. 274 {
    275. 275         struct list_head *first = list->next;
    276. 276         struct list_head *last = list->prev;
    277. 277
    278. 278         first->prev = prev;
    279. 279         prev->next = first;
    280. 280
    281. 281         last->next = next;
    282. 282         next->prev = last;
    283. 283 }
    284. 284
    285. 285 /**
    286. 286  * list_splice - join two lists, this is designed for stacks
    287. 287  * @list: the new list to add.
    288. 288  * @head: the place to add it in the first list.
    289. 289  */
    290. 290 static inline void list_splice(const struct list_head *list,
    291. 291                                 struct list_head *head)
    292. 292 {
    293. 293         if (!list_empty(list))
    294. 294                 __list_splice(list, head, head->next);
    295. 295 }
    296. 296
    297. 297 /**
    298. 298  * list_splice_tail - join two lists, each list being a queue
    299. 299  * @list: the new list to add.
    300. 300  * @head: the place to add it in the first list.
    301. 301  */
    302. 302 static inline void list_splice_tail(struct list_head *list,
    303. 303                                 struct list_head *head)
    304. 304 {
    305. 305         if (!list_empty(list))
    306. 306                 __list_splice(list, head->prev, head);
    307. 307 }
    308. 308
    309. 309 /**
    310. 310  * list_splice_init - join two lists and reinitialise the emptied list.
    311. 311  * @list: the new list to add.
    312. 312  * @head: the place to add it in the first list.
    313. 313  *
    314. 314  * The list at @list is reinitialised
    315. 315  */
    316. 316 static inline void list_splice_init(struct list_head *list,
    317. 317                                     struct list_head *head)
    318. 318 {
    319. 319         if (!list_empty(list)) {
    320. 320                 __list_splice(list, head, head->next);
    321. 321                 INIT_LIST_HEAD(list);
    322. 322         }
    323. 323 }
    324. 324
    325. 325 /**
    326. 326  * list_splice_tail_init - join two lists and reinitialise the emptied list
    327. 327  * @list: the new list to add.
    328. 328  * @head: the place to add it in the first list.
    329. 329  *
    330. 330  * Each of the lists is a queue.
    331. 331  * The list at @list is reinitialised
    332. 332  */
    333. 333 static inline void list_splice_tail_init(struct list_head *list,
    334. 334                                          struct list_head *head)
    335. 335 {
    336. 336         if (!list_empty(list)) {
    337. 337                 __list_splice(list, head->prev, head);
    338. 338                 INIT_LIST_HEAD(list);
    339. 339         }
    340. 340 }
    341. 341
    342. 342 /**
    343. 343  * list_entry - get the struct for this entry
    344. 344  * @ptr:        the &struct list_head pointer.
    345. 345  * @type:       the type of the struct this is embedded in.
    346. 346  * @member:     the name of the list_struct within the struct.
    347. 347  */
    348. 348 #define list_entry(ptr, type, member) \
    349. 349         container_of(ptr, type, member)
    350. 350
    351. 351 /**
    352. 352  * list_first_entry - get the first element from a list
    353. 353  * @ptr:        the list head to take the element from.
    354. 354  * @type:       the type of the struct this is embedded in.
    355. 355  * @member:     the name of the list_struct within the struct.
    356. 356  *
    357. 357  * Note, that list is expected to be not empty.
    358. 358  */
    359. 359 #define list_first_entry(ptr, type, member) \
    360. 360         list_entry((ptr)->next, type, member)
    361. 361
    362. 362 /**
    363. 363  * list_for_each        -       iterate over a list
    364. 364  * @pos:        the &struct list_head to use as a loop cursor.
    365. 365  * @head:       the head for your list.
    366. 366  */
    367. 367 #define list_for_each(pos, head) \
    368. 368         for (pos = (head)->next; prefetch(pos->next), pos != (head); \
    369. 369                 pos = pos->next)
    370. 370
    371. 371 /**
    372. 372  * __list_for_each      -       iterate over a list
    373. 373  * @pos:        the &struct list_head to use as a loop cursor.
    374. 374  * @head:       the head for your list.
    375. 375  *
    376. 376  * This variant differs from list_for_each() in that it's the
    377. 377  * simplest possible list iteration code, no prefetching is done.
    378. 378  * Use this for code that knows the list to be very short (empty
    379. 379  * or 1 entry) most of the time.
    380. 380  */
    381. 381 #define __list_for_each(pos, head) \
    382. 382         for (pos = (head)->next; pos != (head); pos = pos->next)
    383. 383
    384. 384 /**
    385. 385  * list_for_each_prev   -       iterate over a list backwards
    386. 386  * @pos:        the &struct list_head to use as a loop cursor.
    387. 387  * @head:       the head for your list.
    388. 388  */
    389. 389 #define list_for_each_prev(pos, head) \
    390. 390         for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
    391. 391                 pos = pos->prev)
    392. 392
    393. 393 /**
    394. 394  * list_for_each_safe - iterate over a list safe against removal of list entry
    395. 395  * @pos:        the &struct list_head to use as a loop cursor.
    396. 396  * @n:          another &struct list_head to use as temporary storage
    397. 397  * @head:       the head for your list.
    398. 398  */
    399. 399 #define list_for_each_safe(pos, n, head) \
    400. 400         for (pos = (head)->next, n = pos->next; pos != (head); \
    401. 401                 pos = n, n = pos->next)
    402. 402
    403. 403 /**
    404. 404  * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
    405. 405  * @pos:        the &struct list_head to use as a loop cursor.
    406. 406  * @n:          another &struct list_head to use as temporary storage
    407. 407  * @head:       the head for your list.
    408. 408  */
    409. 409 #define list_for_each_prev_safe(pos, n, head) \
    410. 410         for (pos = (head)->prev, n = pos->prev; \
    411. 411              prefetch(pos->prev), pos != (head); \
    412. 412              pos = n, n = pos->prev)
    413. 413
    414. 414 /**
    415. 415  * list_for_each_entry  -       iterate over list of given type
    416. 416  * @pos:        the type * to use as a loop cursor.
    417. 417  * @head:       the head for your list.
    418. 418  * @member:     the name of the list_struct within the struct.
    419. 419  */
    420. 420 #define list_for_each_entry(pos, head, member)                          \
    421. 421         for (pos = list_entry((head)->next, typeof(*pos), member);      \
    422. 422              prefetch(pos->member.next), &pos->member != (head);        \
    423. 423              pos = list_entry(pos->member.next, typeof(*pos), member))
    424. 424
    425. 425 /**
    426. 426  * list_for_each_entry_reverse - iterate backwards over list of given type.
    427. 427  * @pos:        the type * to use as a loop cursor.
    428. 428  * @head:       the head for your list.
    429. 429  * @member:     the name of the list_struct within the struct.
    430. 430  */
    431. 431 #define list_for_each_entry_reverse(pos, head, member)                  \
    432. 432         for (pos = list_entry((head)->prev, typeof(*pos), member);      \
    433. 433              prefetch(pos->member.prev), &pos->member != (head);        \
    434. 434              pos = list_entry(pos->member.prev, typeof(*pos), member))
    435. 435
    436. 436 /**
    437. 437  * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
    438. 438  * @pos:        the type * to use as a start point
    439. 439  * @head:       the head of the list
    440. 440  * @member:     the name of the list_struct within the struct.
    441. 441  *
    442. 442  * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
    443. 443  */
    444. 444 #define list_prepare_entry(pos, head, member) \
    445. 445         ((pos) ? : list_entry(head, typeof(*pos), member))
    446. 446
    447. 447 /**
    448. 448  * list_for_each_entry_continue - continue iteration over list of given type
    449. 449  * @pos:        the type * to use as a loop cursor.
    450. 450  * @head:       the head for your list.
    451. 451  * @member:     the name of the list_struct within the struct.
    452. 452  *
    453. 453  * Continue to iterate over list of given type, continuing after
    454. 454  * the current position.
    455. 455  */
    456. 456 #define list_for_each_entry_continue(pos, head, member)                 \
    457. 457         for (pos = list_entry(pos->member.next, typeof(*pos), member);  \
    458. 458              prefetch(pos->member.next), &pos->member != (head);        \
    459. 459              pos = list_entry(pos->member.next, typeof(*pos), member))
    460. 460
    461. 461 /**
    462. 462  * list_for_each_entry_continue_reverse - iterate backwards from the given point
    463. 463  * @pos:        the type * to use as a loop cursor.
    464. 464  * @head:       the head for your list.
    465. 465  * @member:     the name of the list_struct within the struct.
    466. 466  *
    467. 467  * Start to iterate over list of given type backwards, continuing after
    468. 468  * the current position.
    469. 469  */
    470. 470 #define list_for_each_entry_continue_reverse(pos, head, member)         \
    471. 471         for (pos = list_entry(pos->member.prev, typeof(*pos), member);  \
    472. 472              prefetch(pos->member.prev), &pos->member != (head);        \
    473. 473              pos = list_entry(pos->member.prev, typeof(*pos), member))
    474. 474
    475. 475 /**
    476. 476  * list_for_each_entry_from - iterate over list of given type from the current point
    477. 477  * @pos:        the type * to use as a loop cursor.
    478. 478  * @head:       the head for your list.
    479. 479  * @member:     the name of the list_struct within the struct.
    480. 480  *
    481. 481  * Iterate over list of given type, continuing from current position.
    482. 482  */
    483. 483 #define list_for_each_entry_from(pos, head, member)                     \
    484. 484         for (; prefetch(pos->member.next), &pos->member != (head);      \
    485. 485              pos = list_entry(pos->member.next, typeof(*pos), member))
    486. 486
    487. 487 /**
    488. 488  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
    489. 489  * @pos:        the type * to use as a loop cursor.
    490. 490  * @n:          another type * to use as temporary storage
    491. 491  * @head:       the head for your list.
    492. 492  * @member:     the name of the list_struct within the struct.
    493. 493  */
    494. 494 #define list_for_each_entry_safe(pos, n, head, member)                  \
    495. 495         for (pos = list_entry((head)->next, typeof(*pos), member),      \
    496. 496                 n = list_entry(pos->member.next, typeof(*pos), member); \
    497. 497              &pos->member != (head);                                    \
    498. 498              pos = n, n = list_entry(n->member.next, typeof(*n), member))
    499. 499
    500. 500 /**
    501. 501  * list_for_each_entry_safe_continue - continue list iteration safe against removal
    502. 502  * @pos:        the type * to use as a loop cursor.
    503. 503  * @n:          another type * to use as temporary storage
    504. 504  * @head:       the head for your list.
    505. 505  * @member:     the name of the list_struct within the struct.
    506. 506  *
    507. 507  * Iterate over list of given type, continuing after current point,
    508. 508  * safe against removal of list entry.
    509. 509  */
    510. 510 #define list_for_each_entry_safe_continue(pos, n, head, member)                 \
    511. 511         for (pos = list_entry(pos->member.next, typeof(*pos), member),          \
    512. 512                 n = list_entry(pos->member.next, typeof(*pos), member);         \
    513. 513              &pos->member != (head);                                            \
    514. 514              pos = n, n = list_entry(n->member.next, typeof(*n), member))
    515. 515
    516. 516 /**
    517. 517  * list_for_each_entry_safe_from - iterate over list from current point safe against removal
    518. 518  * @pos:        the type * to use as a loop cursor.
    519. 519  * @n:          another type * to use as temporary storage
    520. 520  * @head:       the head for your list.
    521. 521  * @member:     the name of the list_struct within the struct.
    522. 522  *
    523. 523  * Iterate over list of given type from current point, safe against
    524. 524  * removal of list entry.
    525. 525  */
    526. 526 #define list_for_each_entry_safe_from(pos, n, head, member)                     \
    527. 527         for (n = list_entry(pos->member.next, typeof(*pos), member);            \
    528. 528              &pos->member != (head);                                            \
    529. 529              pos = n, n = list_entry(n->member.next, typeof(*n), member))
    530. 530
    531. 531 /**
    532. 532  * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
    533. 533  * @pos:        the type * to use as a loop cursor.
    534. 534  * @n:          another type * to use as temporary storage
    535. 535  * @head:       the head for your list.
    536. 536  * @member:     the name of the list_struct within the struct.
    537. 537  *
    538. 538  * Iterate backwards over list of given type, safe against removal
    539. 539  * of list entry.
    540. 540  */
    541. 541 #define list_for_each_entry_safe_reverse(pos, n, head, member)          \
    542. 542         for (pos = list_entry((head)->prev, typeof(*pos), member),      \
    543. 543                 n = list_entry(pos->member.prev, typeof(*pos), member); \
    544. 544              &pos->member != (head);                                    \
    545. 545              pos = n, n = list_entry(n->member.prev, typeof(*n), member))
    546. 546
    547. 547 /*
    548. 548  * Double linked lists with a single pointer list head.
    549. 549  * Mostly useful for hash tables where the two pointer list head is
    550. 550  * too wasteful.
    551. 551  * You lose the ability to access the tail in O(1).
    552. 552  */
    553. 553
    554. 554 struct hlist_head {
    555. 555         struct hlist_node *first;
    556. 556 };
    557. 557
    558. 558 struct hlist_node {
    559. 559         struct hlist_node *next, **pprev;
    560. 560 };
    561. 561
    562. 562 #define HLIST_HEAD_INIT { .first = NULL }
    563. 563 #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
    564. 564 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
    565. 565 static inline void INIT_HLIST_NODE(struct hlist_node *h)
    566. 566 {
    567. 567         h->next = NULL;
    568. 568         h->pprev = NULL;
    569. 569 }
    570. 570
    571. 571 static inline int hlist_unhashed(const struct hlist_node *h)
    572. 572 {
    573. 573         return !h->pprev;
    574. 574 }
    575. 575
    576. 576 static inline int hlist_empty(const struct hlist_head *h)
    577. 577 {
    578. 578         return !h->first;
    579. 579 }
    580. 580
    581. 581 static inline void __hlist_del(struct hlist_node *n)
    582. 582 {
    583. 583         struct hlist_node *next = n->next;
    584. 584         struct hlist_node **pprev = n->pprev;
    585. 585         *pprev = next;
    586. 586         if (next)
    587. 587                 next->pprev = pprev;
    588. 588 }
    589. 589
    590. 590 static inline void hlist_del(struct hlist_node *n)
    591. 591 {
    592. 592         __hlist_del(n);
    593. 593         n->next = LIST_POISON1;
    594. 594         n->pprev = LIST_POISON2;
    595. 595 }
    596. 596
    597. 597 static inline void hlist_del_init(struct hlist_node *n)
    598. 598 {
    599. 599         if (!hlist_unhashed(n)) {
    600. 600                 __hlist_del(n);
    601. 601                 INIT_HLIST_NODE(n);
    602. 602         }
    603. 603 }
    604. 604
    605. 605 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
    606. 606 {
    607. 607         struct hlist_node *first = h->first;
    608. 608         n->next = first;
    609. 609         if (first)
    610. 610                 first->pprev = &n->next;
    611. 611         h->first = n;
    612. 612         n->pprev = &h->first;
    613. 613 }
    614. 614
    615. 615 /* next must be != NULL */
    616. 616 static inline void hlist_add_before(struct hlist_node *n,
    617. 617                                         struct hlist_node *next)
    618. 618 {
    619. 619         n->pprev = next->pprev;
    620. 620         n->next = next;
    621. 621         next->pprev = &n->next;
    622. 622         *(n->pprev) = n;
    623. 623 }
    624. 624
    625. 625 static inline void hlist_add_after(struct hlist_node *n,
    626. 626                                         struct hlist_node *next)
    627. 627 {
    628. 628         next->next = n->next;
    629. 629         n->next = next;
    630. 630         next->pprev = &n->next;
    631. 631
    632. 632         if(next->next)
    633. 633                 next->next->pprev  = &next->next;
    634. 634 }
    635. 635
    636. 636 /*
    637. 637  * Move a list from one list head to another. Fixup the pprev
    638. 638  * reference of the first entry if it exists.
    639. 639  */
    640. 640 static inline void hlist_move_list(struct hlist_head *old,
    641. 641                                    struct hlist_head *new)
    642. 642 {
    643. 643         new->first = old->first;
    644. 644         if (new->first)
    645. 645                 new->first->pprev = &new->first;
    646. 646         old->first = NULL;
    647. 647 }
    648. 648
    649. 649 #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
    650. 650
    651. 651 #define hlist_for_each(pos, head) \
    652. 652         for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
    653. 653              pos = pos->next)
    654. 654
    655. 655 #define hlist_for_each_safe(pos, n, head) \
    656. 656         for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
    657. 657              pos = n)
    658. 658
    659. 659 /**
    660. 660  * hlist_for_each_entry - iterate over list of given type
    661. 661  * @tpos:       the type * to use as a loop cursor.
    662. 662  * @pos:        the &struct hlist_node to use as a loop cursor.
    663. 663  * @head:       the head for your list.
    664. 664  * @member:     the name of the hlist_node within the struct.
    665. 665  */
    666. 666 #define hlist_for_each_entry(tpos, pos, head, member)                    \
    667. 667         for (pos = (head)->first;                                        \
    668. 668              pos && ({ prefetch(pos->next); 1;}) &&                      \
    669. 669                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    670. 670              pos = pos->next)
    671. 671
    672. 672 /**
    673. 673  * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
    674. 674  * @tpos:       the type * to use as a loop cursor.
    675. 675  * @pos:        the &struct hlist_node to use as a loop cursor.
    676. 676  * @member:     the name of the hlist_node within the struct.
    677. 677  */
    678. 678 #define hlist_for_each_entry_continue(tpos, pos, member)                 \
    679. 679         for (pos = (pos)->next;                                          \
    680. 680              pos && ({ prefetch(pos->next); 1;}) &&                      \
    681. 681                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    682. 682              pos = pos->next)
    683. 683
    684. 684 /**
    685. 685  * hlist_for_each_entry_from - iterate over a hlist continuing from current point
    686. 686  * @tpos:       the type * to use as a loop cursor.
    687. 687  * @pos:        the &struct hlist_node to use as a loop cursor.
    688. 688  * @member:     the name of the hlist_node within the struct.
    689. 689  */
    690. 690 #define hlist_for_each_entry_from(tpos, pos, member)                     \
    691. 691         for (; pos && ({ prefetch(pos->next); 1;}) &&                    \
    692. 692                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    693. 693              pos = pos->next)
    694. 694
    695. 695 /**
    696. 696  * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
    697. 697  * @tpos:       the type * to use as a loop cursor.
    698. 698  * @pos:        the &struct hlist_node to use as a loop cursor.
    699. 699  * @n:          another &struct hlist_node to use as temporary storage
    700. 700  * @head:       the head for your list.
    701. 701  * @member:     the name of the hlist_node within the struct.
    702. 702  */
    703. 703 #define hlist_for_each_entry_safe(tpos, pos, n, head, member)            \
    704. 704         for (pos = (head)->first;                                        \
    705. 705              pos && ({ n = pos->next; 1; }) &&                           \
    706. 706                 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    707. 707              pos = n)
    708. 708
    709. 709 #endif
    710. 710
     
  2. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Напиши на C++ то же самое. Причём начни с STL, я думаю, что играясь с параметризованными типами из STL можно получить циклический двусвязный список с принудительной связью и с заголовком.
    Или выкини все list_for_each_entry*. Вполне можно обойтись без них.
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    osox
    Не стоит заморачиваться, ядро использует много gcc расширений. Возьмите какую-нибудь библиотеку контейнеров для Cи, libscl к примеру.
     
  4. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Спасибо за ответы

    r90 так и сделал выкинул экзотику на основе list_for_each_entry и иже с ними а что понадобится допишем :)
    пришлось удалить prefetch в некоторых макросах оптимизация
    была ну и container_of заменил на вендовый CONTAINING_RECORD :)

    Booster
    собрал потестил у меня обычно GLIB да GDSL под рукой на венде
    GLIB использую когда для себя что нибудь пишу быстро удобно GDSL деревья :) CURL интернет оброс библиотками :) ну и теперь LIBSCL собрал как статик либу но я специально хотел интрузивный список а в этих либах совсем другая реализация :)
     
  5. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    osox
    В MSVC 10 (студия 2010) есть эквивалент typeof:
    decltype
     
  6. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    green
    у меня на С код :)
    Код (Text):
    1. int main(void)
    2. {
    3.     int i;
    4.     decltype(i) j;
    5.     return 0;
    6. }
    Compile as C Code(/TC)
    'decltype' undefined; assuming extern returning int
    он считает его за идентификатор функции :)
    а gcc это компилит нормально :)
    Код (Text):
    1. int main(void)
    2. {
    3.     int i;
    4.     typeof(i) j;
    5.     return 0;
    6. }
    вот если бы для С аналог typeof был :)
     
  7. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    osox
    Сорри, не проверил - думал, они и для С его сделали...
     
  8. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Ежики плакали, кололись, но продолжали писать на С.
     
  9. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    J0E
    Да-да. Мы знаем эту точку зрения. Вовсе не обязательно озвучивать её ещё раз.
     
  10. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    J0E - ёжик тужился, пыхтел - но всё равно пёр на себе два плюса.
    А то как же, в наше время без плюсов не модно.
    Что ты за ёжик если плюсов не притянул, а одни яблоки :)
     
  11. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Какие причины использовать /TC кроме упертости? Все равно typeof уже отказ от С.

    Знания не утяжеляют мозг) Не осилил сам -- помолчи.
     
  12. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    J0E
    Чего ты ведёшь себя как ребёнок? Сходи в гугл, почитай и не задавай больше глупых вопросов.
     
  13. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    При чём здесь осилил/не осилил?
    Человек что, спрашивал на чём ему писать?
    По-моему очевидно что пишет он на Си, и совет ему нужен с учётом этого.
    С таким же успехом мог бы Javascript посоветовать - там typeof есть.
     
  14. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Все ж задам. Сходил, там поля ввода и 2 кнопки. Что делать дальше?
    Очевидно что он использует на MSVC, то есть платформу не имеющую проблем с С++
     
  15. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    J0E
    Как говаривал мой папа: снимать штаны и бегать.
     
  16. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    К счастью, я не приучен добиваться результата сниманием штанов. Всегда есть другие способы. Поэтому не понятно какие проблемы у твоего первого совета, или №5.

    ЗЫ Специально для тех кому очевидно использование С привожу список его ключевых слов, очнитесь:
    auto break case char const continue default do double else enum extern float for goto if inline int long register restrict return short signed sizeof static struct switch typedef union unsigned void volatile while _Bool _Complex _Imaginary
     
  17. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    J0E
    Я был прав, ты не готов принимать информацию. Ты пришёл сюда доказывать свою оффтопичную правоту, но уши твои закрыты, ты не услышишь меня, даже если я переборю свою лень, и нырну в предлагаемый тобою холивар.
     
  18. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Написать киворды для гугла занимает меньше времени, чем сочинять про якобы правоту (где ты утверждал о моей неготовности?) так что не надо обманывать(ся) ленью. И не надо приписывать мне разжигание холиваров, мне эти споры совершенно не интересны, я неплохо понимаю разницу между языками и вряд ли узнаю в результате что-то новое. Если на кого-то ++ действует как красная тряпка -- так нечо на зеркало пенять, я называю это упертостью и некомпетентностью поскольку сам через это прошел ;) и знаю что кто-то в результате шоковой терапии чему-то научится, а кому не дано так что ж.

    Еще я видел приличные С библиотеки которые вполне нормально собиралиcь с /TP потому что авторы задумывались о портабельности и писали явные касты от void*. Вот мне и неясно желание ограничивать себя /TC (рантайм поддержка для требуемой фичи не требуется). Если бы автор темы написал "мне нельзя использовать новую студию" я бы молча прошел мимо.

    В скрываемой тобой информации ничего секретного нет, мог бы оставить ее для других, ведь форум публичный, какой смысл учить единственного персонажа, не несущего дезинформацию?
     
  19. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    J0E
    Ты упорен. Это хорошее качество. Но, ты ошибаешься, считая что я обязан нести свет в массы. Я сложил эту задачу с себя, уже почти год назад. Кроме того, этот топик не требует продолжения: те кто хотел знать ответы на твои вопросы, уже узнали в гугле. Те кто знать не хотел, не узнают, чтобы я здесь не написал.
    J0E
    Ты не прав. Перечитай топик. Два раза. Или столько раз, сколько потребуется для просветления.

    Прочитал? Просветление пришло? А теперь я открою тебе более глубокую мудрость. Подумай о том, что случится, если я соберу аргументы из гугла и изложу их здесь. Подумай, и согласись с тем, что увидев аргументы, ты сочтёшь своим долгом их все опровергнуть. Согласись также с тем, что придёт ещё парочка человек, и тоже начнёт опровергать. Потом придёт ещё три человека и начнут опровергать опровержения. Вы же начнёте опровергать опровержения опровержений. И так далее... До бесконечности. То есть тут будет холивар. Так? А кто будет виновником этого холивара? Ты, не так ли? Ведь это ты убеждаешь меня начать рассказывать тут о преимуществах C.
     
  20. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    r90
    просто напиши зачем нужен С в тех случаях когда можно писать на С++