genode/repos/base/include/util/list.h

141 lines
2.8 KiB
C
Raw Normal View History

2011-12-22 15:19:25 +00:00
/*
* \brief Single connected list
* \author Norman Feske
* \date 2006-08-02
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
2011-12-22 15:19:25 +00:00
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
2011-12-22 15:19:25 +00:00
*/
#ifndef _INCLUDE__UTIL__LIST_H_
#define _INCLUDE__UTIL__LIST_H_
namespace Genode {
template <typename> class List;
template <typename> class List_element;
}
2011-12-22 15:19:25 +00:00
/**
* Single-connected list
*
* \param LT list element type
*/
template <typename LT>
class Genode::List
{
private:
LT *_first;
public:
class Element
{
protected:
friend class List;
LT mutable *_next;
public:
Element(): _next(0) { }
/**
* Return next element in list
*/
LT *next() const { return _next; }
};
public:
/**
* Constructor
*/
List() : _first(0) { }
/**
* Return first list element
*/
LT *first() { return _first; }
LT const *first() const { return _first; }
/**
* Insert element after specified element into list
*
* \param le list element to insert
* \param at target position (preceding list element)
*/
void insert(LT const *le, LT const *at = 0)
{
/* insert at beginning of the list */
if (at == 0) {
base: Make Genode::List clang friendly. Clang is generally fine with Genode::List and compiles code using it without emitting any warnings. There is however one exception. Clang fails hard when building base-hw/src/core/kernel/object.cc. This is due to a call to Genode::List::remove made from Object_identity::invalidate function. The error message clang produces is: list.h:96:33: error: 'Genode::List<Kernel::Object_identity_reference>::Element::_next' is not a member of class 'const Kernel::Object_identity' _first = le->List::Element::_next; ~~~~~~~~~~~~~~~^ When we look at the declaration of the Kernel::Object class on which the remove method is called. as expected it does inherit Genode::List: using Object_identity_list = Genode::List<Kernel::Object_identity>; class Kernel::Object : private Object_identity_list { ... } Given the error message we see that List::Element should be resolved to Genode::List<Kernel::Object_identity>::Element, and not Genode::List<Kernel::Object_identity_reference>::Element. But how does clang manage to figure out we're talking about Object_identity_refecence list here? Well, I admit I don't know the exact steps it takes to arrive at this conclusion, but it is not entirely wrong. If we take a look at what Kernel::Object_identity is we'll see: class Kernel::Object_identity : public Object_identity_list::Element, public Kernel::Object_identity_reference_list { ... } Where as one can guess Object_identity_reference_list is defined as: using Object_identity_reference_list = Genode::List<Object_identity_reference>; Long story short Kernel::Object has Genode::List of both Kernel::Object_identity and Kernel::Object_identity_reference in its inheritance chain and clang is not really sure to which of those the code refers to in Genode::List::remove method by using List::Element::. The fix for this is relatively simple, explicitly state the full type of the base class the code intends to refer to. Replacing List::Element, with List<LT>::Element makes the code buildable with both clang and GCC. Fixes #3990
2021-01-12 23:12:49 +00:00
le->List<LT>::Element::_next = _first;
_first = const_cast<LT *>(le);
} else {
base: Make Genode::List clang friendly. Clang is generally fine with Genode::List and compiles code using it without emitting any warnings. There is however one exception. Clang fails hard when building base-hw/src/core/kernel/object.cc. This is due to a call to Genode::List::remove made from Object_identity::invalidate function. The error message clang produces is: list.h:96:33: error: 'Genode::List<Kernel::Object_identity_reference>::Element::_next' is not a member of class 'const Kernel::Object_identity' _first = le->List::Element::_next; ~~~~~~~~~~~~~~~^ When we look at the declaration of the Kernel::Object class on which the remove method is called. as expected it does inherit Genode::List: using Object_identity_list = Genode::List<Kernel::Object_identity>; class Kernel::Object : private Object_identity_list { ... } Given the error message we see that List::Element should be resolved to Genode::List<Kernel::Object_identity>::Element, and not Genode::List<Kernel::Object_identity_reference>::Element. But how does clang manage to figure out we're talking about Object_identity_refecence list here? Well, I admit I don't know the exact steps it takes to arrive at this conclusion, but it is not entirely wrong. If we take a look at what Kernel::Object_identity is we'll see: class Kernel::Object_identity : public Object_identity_list::Element, public Kernel::Object_identity_reference_list { ... } Where as one can guess Object_identity_reference_list is defined as: using Object_identity_reference_list = Genode::List<Object_identity_reference>; Long story short Kernel::Object has Genode::List of both Kernel::Object_identity and Kernel::Object_identity_reference in its inheritance chain and clang is not really sure to which of those the code refers to in Genode::List::remove method by using List::Element::. The fix for this is relatively simple, explicitly state the full type of the base class the code intends to refer to. Replacing List::Element, with List<LT>::Element makes the code buildable with both clang and GCC. Fixes #3990
2021-01-12 23:12:49 +00:00
le->List<LT>::Element::_next = at->List<LT>::Element::_next;
at->List<LT>::Element::_next = const_cast<LT *>(le);
}
}
/**
* Remove element from list
*/
void remove(LT const *le)
{
if (!_first) return;
2011-12-22 15:19:25 +00:00
/* if specified element is the first of the list */
if (le == _first) {
base: Make Genode::List clang friendly. Clang is generally fine with Genode::List and compiles code using it without emitting any warnings. There is however one exception. Clang fails hard when building base-hw/src/core/kernel/object.cc. This is due to a call to Genode::List::remove made from Object_identity::invalidate function. The error message clang produces is: list.h:96:33: error: 'Genode::List<Kernel::Object_identity_reference>::Element::_next' is not a member of class 'const Kernel::Object_identity' _first = le->List::Element::_next; ~~~~~~~~~~~~~~~^ When we look at the declaration of the Kernel::Object class on which the remove method is called. as expected it does inherit Genode::List: using Object_identity_list = Genode::List<Kernel::Object_identity>; class Kernel::Object : private Object_identity_list { ... } Given the error message we see that List::Element should be resolved to Genode::List<Kernel::Object_identity>::Element, and not Genode::List<Kernel::Object_identity_reference>::Element. But how does clang manage to figure out we're talking about Object_identity_refecence list here? Well, I admit I don't know the exact steps it takes to arrive at this conclusion, but it is not entirely wrong. If we take a look at what Kernel::Object_identity is we'll see: class Kernel::Object_identity : public Object_identity_list::Element, public Kernel::Object_identity_reference_list { ... } Where as one can guess Object_identity_reference_list is defined as: using Object_identity_reference_list = Genode::List<Object_identity_reference>; Long story short Kernel::Object has Genode::List of both Kernel::Object_identity and Kernel::Object_identity_reference in its inheritance chain and clang is not really sure to which of those the code refers to in Genode::List::remove method by using List::Element::. The fix for this is relatively simple, explicitly state the full type of the base class the code intends to refer to. Replacing List::Element, with List<LT>::Element makes the code buildable with both clang and GCC. Fixes #3990
2021-01-12 23:12:49 +00:00
_first = le->List<LT>::Element::_next;
2011-12-22 15:19:25 +00:00
} else {
2011-12-22 15:19:25 +00:00
/* search specified element in the list */
Element *e = _first;
while (e->_next && (e->_next != le))
e = e->_next;
2011-12-22 15:19:25 +00:00
/* element is not member of the list */
if (!e->_next) return;
2011-12-22 15:19:25 +00:00
/* e->_next is the element to remove, skip it in list */
base: Make Genode::List clang friendly. Clang is generally fine with Genode::List and compiles code using it without emitting any warnings. There is however one exception. Clang fails hard when building base-hw/src/core/kernel/object.cc. This is due to a call to Genode::List::remove made from Object_identity::invalidate function. The error message clang produces is: list.h:96:33: error: 'Genode::List<Kernel::Object_identity_reference>::Element::_next' is not a member of class 'const Kernel::Object_identity' _first = le->List::Element::_next; ~~~~~~~~~~~~~~~^ When we look at the declaration of the Kernel::Object class on which the remove method is called. as expected it does inherit Genode::List: using Object_identity_list = Genode::List<Kernel::Object_identity>; class Kernel::Object : private Object_identity_list { ... } Given the error message we see that List::Element should be resolved to Genode::List<Kernel::Object_identity>::Element, and not Genode::List<Kernel::Object_identity_reference>::Element. But how does clang manage to figure out we're talking about Object_identity_refecence list here? Well, I admit I don't know the exact steps it takes to arrive at this conclusion, but it is not entirely wrong. If we take a look at what Kernel::Object_identity is we'll see: class Kernel::Object_identity : public Object_identity_list::Element, public Kernel::Object_identity_reference_list { ... } Where as one can guess Object_identity_reference_list is defined as: using Object_identity_reference_list = Genode::List<Object_identity_reference>; Long story short Kernel::Object has Genode::List of both Kernel::Object_identity and Kernel::Object_identity_reference in its inheritance chain and clang is not really sure to which of those the code refers to in Genode::List::remove method by using List::Element::. The fix for this is relatively simple, explicitly state the full type of the base class the code intends to refer to. Replacing List::Element, with List<LT>::Element makes the code buildable with both clang and GCC. Fixes #3990
2021-01-12 23:12:49 +00:00
e->List<LT>::Element::_next = e->List<LT>::Element::_next->List<LT>::Element::_next;
2011-12-22 15:19:25 +00:00
}
base: Make Genode::List clang friendly. Clang is generally fine with Genode::List and compiles code using it without emitting any warnings. There is however one exception. Clang fails hard when building base-hw/src/core/kernel/object.cc. This is due to a call to Genode::List::remove made from Object_identity::invalidate function. The error message clang produces is: list.h:96:33: error: 'Genode::List<Kernel::Object_identity_reference>::Element::_next' is not a member of class 'const Kernel::Object_identity' _first = le->List::Element::_next; ~~~~~~~~~~~~~~~^ When we look at the declaration of the Kernel::Object class on which the remove method is called. as expected it does inherit Genode::List: using Object_identity_list = Genode::List<Kernel::Object_identity>; class Kernel::Object : private Object_identity_list { ... } Given the error message we see that List::Element should be resolved to Genode::List<Kernel::Object_identity>::Element, and not Genode::List<Kernel::Object_identity_reference>::Element. But how does clang manage to figure out we're talking about Object_identity_refecence list here? Well, I admit I don't know the exact steps it takes to arrive at this conclusion, but it is not entirely wrong. If we take a look at what Kernel::Object_identity is we'll see: class Kernel::Object_identity : public Object_identity_list::Element, public Kernel::Object_identity_reference_list { ... } Where as one can guess Object_identity_reference_list is defined as: using Object_identity_reference_list = Genode::List<Object_identity_reference>; Long story short Kernel::Object has Genode::List of both Kernel::Object_identity and Kernel::Object_identity_reference in its inheritance chain and clang is not really sure to which of those the code refers to in Genode::List::remove method by using List::Element::. The fix for this is relatively simple, explicitly state the full type of the base class the code intends to refer to. Replacing List::Element, with List<LT>::Element makes the code buildable with both clang and GCC. Fixes #3990
2021-01-12 23:12:49 +00:00
le->List<LT>::Element::_next = 0;
}
};
/**
* Helper for using member variables as list elements
*
* \param T type of compound object to be organized in a list
*
* This helper allow the creation of lists that use member variables to
* connect their elements. This way, the organized type does not need to
* publicly inherit 'List<LT>::Element'. Furthermore objects can easily
* be organized in multiple lists by embedding multiple 'List_element'
* member variables.
*/
template <typename T>
class Genode::List_element : public List<List_element<T> >::Element
{
T *_object;
public:
List_element(T *object) : _object(object) { }
T *object() const { return _object; }
};
2011-12-22 15:19:25 +00:00
#endif /* _INCLUDE__UTIL__LIST_H_ */