diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-05-11 14:13:47 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-05-20 11:36:06 +0200 |
commit | dfef28de887eba43747bca52584f8310450e243a (patch) | |
tree | 832955e5ad880c2913bc55b7c8217fc34bc9570c /src/cxx_linuxlist.h | |
parent | 67c385046dbf4fe00871bb9f56b6b82e1f9d1348 (diff) |
llist: Add a C++ wrapper for linux_list
This commit adds the LListHead class which is a wrapper around the
linuxlist. It adds an additional member to refer to the container,
since the container_of macro doesn't work properly with C++ classes.
All functions and macros from linuxlist.h are support except for the
entry macros (e.g. llist_entry, llist_for_each_entry, ...). To access
the container (entry), an entry() method is provided instead:
llist_for_each(pos, &elems) {
pos->entry()->do_something();
}
Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/cxx_linuxlist.h')
-rw-r--r-- | src/cxx_linuxlist.h | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/cxx_linuxlist.h b/src/cxx_linuxlist.h new file mode 100644 index 00000000..d9b28c44 --- /dev/null +++ b/src/cxx_linuxlist.h @@ -0,0 +1,133 @@ +/* cxx_linuxlist.h + * + * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH + * Author: Jacob Erlbeck <jerlbeck@sysmocom.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#pragma once + +extern "C" { + #include <osmocom/core/linuxlist.h> +} + +template <typename T> +struct LListHead { + typedef T entry_t; + + /* This must match the declaration of struct llist_head */ + LListHead<T> *next; + LListHead<T> *prev; + + LListHead() : m_back(0) { INIT_LLIST_HEAD(this); } + LListHead(T* entry) : m_back(entry) { + next = (LListHead<T> *)LLIST_POISON1; + prev = (LListHead<T> *)LLIST_POISON2; + } + + T *entry() {return m_back;} + const T *entry() const {return m_back;} + + llist_head &llist() { + return *static_cast<llist_head *>(static_cast<void *>(this)); + } + const llist_head &llist() const { + return *static_cast<llist_head *>(static_cast<void *>(this)); + } + +private: + T *const m_back; +}; + +/* Define a family of casting functions */ +template <typename T> +llist_head &llist(LListHead<T> &l) +{ + return l->llist(); +} + +template <typename T> +const llist_head &llist(const LListHead<T> &l) +{ + return l->llist(); +} + +template <typename T> +llist_head *llptr(LListHead<T> *l) +{ + return &(l->llist()); +} + +template <typename T> +const llist_head *llptr(const LListHead<T> *l) +{ + return &(l->llist()); +} + +/* Define type-safe wrapper for the existing linux_list.h functions */ +template <typename T> +inline void llist_add(LListHead<T> *new_, LListHead<T> *head) +{ + llist_add(llptr(new_), llptr(head)); +} + +template <typename T> +inline void llist_add_tail(LListHead<T> *new_, LListHead<T> *head) +{ + llist_add_tail(llptr(new_), llptr(head)); +} + +template <typename T> +inline void llist_del(LListHead<T> *entry) +{ + llist_del(llptr(entry)); +} + +template <typename T> +inline void llist_del_init(LListHead<T> *entry) +{ + llist_del_init(llptr(entry)); +} + +template <typename T> +inline void llist_move(LListHead<T> *list, LListHead<T> *head) +{ + llist_move(llptr(list), llptr(head)); +} + +template <typename T> +inline void llist_move_tail(LListHead<T> *list, LListHead<T> *head) +{ + llist_move_tail(llptr(list), llptr(head)); +} + +template <typename T> +inline int llist_empty(const LListHead<T> *head) +{ + return llist_empty(llptr(head)); +} + +template <typename T> +inline void llist_splice(LListHead<T> *list, LListHead<T> *head) +{ + llist_splice(llptr(list), llptr(head)); +} + +template <typename T> +inline void llist_splice_init(LListHead<T> *list, LListHead<T> *head) +{ + llist_splice_init(llptr(list), llptr(head)); +} |