1  /*
   2   * \brief  Single connected list
   3   * \author Norman Feske
   4   * \date   2006-08-02
   5   */

   6  
   7  /*
   8   * Copyright (C) 2006-2013 Genode Labs GmbH
   9   *
  10   * This file is part of the Genode OS framework, which is distributed
  11   * under the terms of the GNU General Public License version 2.
  12   */

  13  
  14  #ifndef _INCLUDE__UTIL__LIST_H_
  15  #define _INCLUDE__UTIL__LIST_H_
  16  
  17  namespace Genode {
  18  
  19     template <typename> class List;
  20     template <typename> class List_element;
  21  }

  22  
  23  
  24  /**
  25   * Single-connected list
  26   *
  27   * \param LT  list element type
  28   */

  29  template <typename LT>
  30  class Genode::List
  31  {
  32     private:
  33  
  34        LT *_first;

  35  
  36     public:
  37  
  38        class Element
  39        {
  40           protected:
  41  
  42              friend class List;
  43  
  44              LT mutable *_next;

  45  
  46           public:
  47  
  48              Element(): _next(0) { }
  49  
  50              /**
  51               * Return next element in list
  52               */

  53              LT *next() const { return _next; }

  54        }
;

  55  
  56     public:
  57  
  58        /**
  59         * Constructor
  60         */

  61        List() : _first(0) { }

  62  
  63        /**
  64         * Return first list element
  65         */

  66        LT       *first()       { return _first; }

  67        LT const *first() const { return _first; }
  68  
  69        /**
  70         * Insert element after specified element into list
  71         *
  72         * \param  le  list element to insert
  73         * \param  at  target position (preceding list element)
  74         */

  75        void insert(LT const *le, LT const *at = 0)
  76        {
  77           /* insert at beginning of the list */
  78           if (at == 0) {
  79              le->Element::_next = _first;
  80              _first = const_cast<LT *>(le);

  81           }
 else {
  82              le->Element::_next = at->Element::_next;
  83              at->Element::_next = const_cast<LT *>(le);

  84           }

  85        }

  86  
  87        /**
  88         * Remove element from list
  89         */

  90        void remove(LT const *le)
  91        {
  92           if (!_first) return;
  93  
  94           /* if specified element is the first of the list */
  95           if (le == _first) {
  96              _first = le->Element::_next;
  97  
  98           }
 else {
  99  
 100              /* search specified element in the list */
 101              Element *= _first;
 102              while (e->_next && (e->_next != le))
 103                 = e->_next;

 104  
 105              /* element is not member of the list */
 106              if (!e->_next) return;
 107  
 108              /* e->_next is the element to remove, skip it in list */
 109              e->Element::_next = e->Element::_next->Element::_next;

 110           }

 111  
 112           le->Element::_next = 0;

 113        }

 114  }
;

 115  
 116  
 117  /**
 118   * Helper for using member variables as list elements
 119   *
 120   * \param T  type of compound object to be organized in a list
 121   *
 122   * This helper allow the creation of lists that use member variables to
 123   * connect their elements. This way, the organized type does not need to
 124   * publicly inherit `List<LT>::Element`. Furthermore objects can easily
 125   * be organized in multiple lists by embedding multiple `List_element`
 126   * member variables.
 127   */

 128  template <typename T>
 129  class Genode::List_element : public List<List_element<T> >::Element
 130  {
 131     *_object;
 132  
 133     public:
 134  
 135        List_element(*object) : _object(object) { }
 136  
 137        *object() const { return _object; }

 138  }
;

 139  
 140  #endif /* _INCLUDE__UTIL__LIST_H_ */