blob: 1562bfe1ebfc76e00b6f085c9d3c6ce75008bfc1 [file] [log] [blame]
Jacob Erlbeckdfef28d2015-05-11 14:13:47 +02001/* cxx_linuxlist.h
2 *
3 * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Jacob Erlbeckdfef28d2015-05-11 14:13:47 +020015 */
16
17#pragma once
18
19extern "C" {
20 #include <osmocom/core/linuxlist.h>
21}
22
23template <typename T>
24struct LListHead {
25 typedef T entry_t;
26
27 /* This must match the declaration of struct llist_head */
28 LListHead<T> *next;
29 LListHead<T> *prev;
30
31 LListHead() : m_back(0) { INIT_LLIST_HEAD(this); }
32 LListHead(T* entry) : m_back(entry) {
33 next = (LListHead<T> *)LLIST_POISON1;
34 prev = (LListHead<T> *)LLIST_POISON2;
35 }
36
37 T *entry() {return m_back;}
38 const T *entry() const {return m_back;}
39
40 llist_head &llist() {
41 return *static_cast<llist_head *>(static_cast<void *>(this));
42 }
43 const llist_head &llist() const {
Jacob Erlbeckaf387e22015-08-21 12:05:30 +020044 return *static_cast<const llist_head *>(static_cast<const void *>(this));
Jacob Erlbeckdfef28d2015-05-11 14:13:47 +020045 }
46
47private:
48 T *const m_back;
49};
50
51/* Define a family of casting functions */
52template <typename T>
53llist_head &llist(LListHead<T> &l)
54{
55 return l->llist();
56}
57
58template <typename T>
59const llist_head &llist(const LListHead<T> &l)
60{
61 return l->llist();
62}
63
64template <typename T>
65llist_head *llptr(LListHead<T> *l)
66{
67 return &(l->llist());
68}
69
70template <typename T>
71const llist_head *llptr(const LListHead<T> *l)
72{
73 return &(l->llist());
74}
75
76/* Define type-safe wrapper for the existing linux_list.h functions */
77template <typename T>
78inline void llist_add(LListHead<T> *new_, LListHead<T> *head)
79{
80 llist_add(llptr(new_), llptr(head));
81}
82
83template <typename T>
84inline void llist_add_tail(LListHead<T> *new_, LListHead<T> *head)
85{
86 llist_add_tail(llptr(new_), llptr(head));
87}
88
89template <typename T>
90inline void llist_del(LListHead<T> *entry)
91{
92 llist_del(llptr(entry));
93}
94
95template <typename T>
96inline void llist_del_init(LListHead<T> *entry)
97{
98 llist_del_init(llptr(entry));
99}
100
101template <typename T>
102inline void llist_move(LListHead<T> *list, LListHead<T> *head)
103{
104 llist_move(llptr(list), llptr(head));
105}
106
107template <typename T>
108inline void llist_move_tail(LListHead<T> *list, LListHead<T> *head)
109{
110 llist_move_tail(llptr(list), llptr(head));
111}
112
113template <typename T>
114inline int llist_empty(const LListHead<T> *head)
115{
116 return llist_empty(llptr(head));
117}
118
119template <typename T>
120inline void llist_splice(LListHead<T> *list, LListHead<T> *head)
121{
122 llist_splice(llptr(list), llptr(head));
123}
124
125template <typename T>
126inline void llist_splice_init(LListHead<T> *list, LListHead<T> *head)
127{
128 llist_splice_init(llptr(list), llptr(head));
129}